Merge pull request #1478 from eallison91/dev/ssl_cipher_support
Dev/ssl cipher support
This commit is contained in:
commit
e4255d03fb
12
README.md
12
README.md
|
@ -157,10 +157,20 @@ $ puma -b 'unix:///var/run/puma.sock?umask=0111'
|
|||
```
|
||||
|
||||
Need a bit of security? Use SSL sockets:
|
||||
|
||||
```
|
||||
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert'
|
||||
```
|
||||
#### Controlling SSL Cipher Suites
|
||||
Need to use or avoid specific SSL cipher suites? Use ssl_cipher_filter or ssl_cipher_list options.
|
||||
#####Ruby:
|
||||
```
|
||||
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&ssl_cipher_filter=!aNULL:AES+SHA'
|
||||
```
|
||||
#####JRuby:
|
||||
```
|
||||
$ puma -b 'ssl://127.0.0.1:9292?keystore=path_to_keystore&keystore-pass=keystore_password&ssl_cipher_list=TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA'
|
||||
```
|
||||
See https://www.openssl.org/docs/man1.0.2/apps/ciphers.html for cipher filter format and full list of cipher suites.
|
||||
|
||||
### Control/Status Server
|
||||
|
||||
|
|
|
@ -161,6 +161,9 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|||
ID sym_verify_mode = rb_intern("verify_mode");
|
||||
VALUE verify_mode = rb_funcall(mini_ssl_ctx, sym_verify_mode, 0);
|
||||
|
||||
ID sym_ssl_cipher_filter = rb_intern("ssl_cipher_filter");
|
||||
VALUE ssl_cipher_filter = rb_funcall(mini_ssl_ctx, sym_ssl_cipher_filter, 0);
|
||||
|
||||
ctx = SSL_CTX_new(SSLv23_server_method());
|
||||
conn->ctx = ctx;
|
||||
|
||||
|
@ -175,7 +178,13 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|||
SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION);
|
||||
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
|
||||
|
||||
SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
|
||||
if (!NIL_P(ssl_cipher_filter)) {
|
||||
StringValue(ssl_cipher_filter);
|
||||
SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(ssl_cipher_filter));
|
||||
}
|
||||
else {
|
||||
SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
|
||||
}
|
||||
|
||||
DH *dh = get_dh1024();
|
||||
SSL_CTX_set_tmp_dh(ctx, dh);
|
||||
|
|
|
@ -170,6 +170,12 @@ public class MiniSSL extends RubyObject {
|
|||
engine.setNeedClientAuth(true);
|
||||
}
|
||||
|
||||
IRubyObject sslCipherListObject = miniSSLContext.callMethod(threadContext, "ssl_cipher_list");
|
||||
if (!sslCipherListObject.isNil()) {
|
||||
String[] sslCipherList = sslCipherListObject.convertToString().asJavaString().split(",");
|
||||
engine.setEnabledCipherSuites(sslCipherList);
|
||||
}
|
||||
|
||||
SSLSession session = engine.getSession();
|
||||
inboundNetData = new MiniSSLBuffer(session.getPacketBufferSize());
|
||||
outboundAppData = new MiniSSLBuffer(session.getApplicationBufferSize());
|
||||
|
|
|
@ -162,6 +162,7 @@ module Puma
|
|||
end
|
||||
|
||||
ctx.keystore_pass = params['keystore-pass']
|
||||
ctx.ssl_cipher_list = params['ssl_cipher_list'] if params['ssl_cipher_list']
|
||||
else
|
||||
unless params['key']
|
||||
@events.error "Please specify the SSL key via 'key='"
|
||||
|
@ -182,6 +183,7 @@ module Puma
|
|||
end
|
||||
|
||||
ctx.ca = params['ca'] if params['ca']
|
||||
ctx.ssl_cipher_filter = params['ssl_cipher_filter'] if params['ssl_cipher_filter']
|
||||
end
|
||||
|
||||
if params['verify_mode']
|
||||
|
@ -313,6 +315,7 @@ module Puma
|
|||
s.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
|
||||
s.listen backlog
|
||||
|
||||
|
||||
ssl = MiniSSL::Server.new s, ctx
|
||||
env = @proto_env.dup
|
||||
env[HTTPS_KEY] = HTTPS
|
||||
|
|
|
@ -180,6 +180,7 @@ module Puma
|
|||
# jruby-specific Context properties: java uses a keystore and password pair rather than a cert/key pair
|
||||
attr_reader :keystore
|
||||
attr_accessor :keystore_pass
|
||||
attr_accessor :ssl_cipher_list
|
||||
|
||||
def keystore=(keystore)
|
||||
raise ArgumentError, "No such keystore file '#{keystore}'" unless File.exist? keystore
|
||||
|
@ -195,6 +196,7 @@ module Puma
|
|||
attr_reader :key
|
||||
attr_reader :cert
|
||||
attr_reader :ca
|
||||
attr_accessor :ssl_cipher_filter
|
||||
|
||||
def key=(key)
|
||||
raise ArgumentError, "No such key file '#{key}'" unless File.exist? key
|
||||
|
|
|
@ -28,4 +28,32 @@ class TestBinder < Minitest::Test
|
|||
|
||||
assert_equal [], @binder.listeners
|
||||
end
|
||||
|
||||
def test_binder_parses_ssl_cipher_filter
|
||||
skip_on_appveyor
|
||||
skip_on_jruby
|
||||
|
||||
key = File.expand_path "../../examples/puma/puma_keypair.pem", __FILE__
|
||||
cert = File.expand_path "../../examples/puma/cert_puma.pem", __FILE__
|
||||
ssl_cipher_filter = "AES@STRENGTH"
|
||||
|
||||
@binder.parse(["ssl://0.0.0.0?key=#{key}&cert=#{cert}&ssl_cipher_filter=#{ssl_cipher_filter}"], @events)
|
||||
|
||||
ssl = @binder.instance_variable_get(:@ios)[0]
|
||||
ctx = ssl.instance_variable_get(:@ctx)
|
||||
assert_equal(ssl_cipher_filter, ctx.ssl_cipher_filter)
|
||||
end
|
||||
|
||||
def test_binder_parses_jruby_ssl_options
|
||||
skip unless Puma.jruby?
|
||||
|
||||
keystore = File.expand_path "../../examples/puma/keystore.jks", __FILE__
|
||||
ssl_cipher_list = "TLS_DHE_RSA_WITH_DES_CBC_SHA,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"
|
||||
@binder.parse(["ssl://0.0.0.0?keystore=#{keystore}&ssl_cipher_list=#{ssl_cipher_list}"], @events)
|
||||
|
||||
ssl= @binder.instance_variable_get(:@ios)[0]
|
||||
ctx = ssl.instance_variable_get(:@ctx)
|
||||
assert_equal(keystore, ctx.keystore)
|
||||
assert_equal(ssl_cipher_list, ctx.ssl_cipher_list)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue