diff --git a/doc/guide.tex b/doc/guide.tex
index f840550ec..cae2694d2 100644
--- a/doc/guide.tex
+++ b/doc/guide.tex
@@ -333,7 +333,7 @@ To compile \ejabberd{} on a `Unix-like' operating system, you need:
 \makesubsection{download}{Download Source Code}
 \ind{install!download}
 
-Released versions of \ejabberd{} are available in the ProcessOne \ejabberd{} downloads page:
+Released versions of \ejabberd{} are available in the ProcessOne \ejabberd{} downloads page:
 \ahrefurl{http://www.process-one.net/en/ejabberd/downloads}
 
 \ind{Git repository}
@@ -870,7 +870,7 @@ The available modules, their purpose and the options allowed by each one are:
 \begin{description}
   \titem{\texttt{ejabberd\_c2s}}
     Handles c2s connections.\\
-    Options: \texttt{access}, \texttt{certfile}, \texttt{ciphers},
+    Options: \texttt{access}, \texttt{certfile}, \texttt{ciphers}, \texttt{protocol\_options}
     \texttt{max\_fsm\_queue},
     \texttt{max\_stanza\_size}, \texttt{shaper},
     \texttt{starttls}, \texttt{starttls\_required}, \texttt{tls},
@@ -918,6 +918,10 @@ This is a detailed description of each option allowed by the listening modules:
     To define a certificate file specific for a given domain, use the global option \term{domain\_certfile}.
   \titem{ciphers: Ciphers} OpenSSL ciphers list in the same format accepted by
   `\verb|openssl ciphers|' command.
+  \titem{protocol\_options: ProtocolOpts} \ind{options!protocol\_options}
+  List of general options relating to SSL/TLS. These map to \verb|<a href="https://www.openssl.org/docs/ssl/SSL_CTX_set_options.html">OpenSSL's set_options()</a>|.
+  For a full list of options available in ejabberd, \verb|<a href="https://github.com/processone/tls/blob/protocol_options/c_src/options.h">see the source</a>|.
+  The default entry is: \verb|"no_sslv2"|
   \titem{default\_host: undefined|HostName\}}
     If the HTTP request received by ejabberd contains the HTTP header \term{Host}
     with an ambiguous virtual host that doesn't match any one defined in ejabberd (see \ref{hostnames}),
@@ -1066,6 +1070,10 @@ There are some additional global options that can be specified in the ejabberd c
   Full path to the file containing the SSL certificate for a specific domain.
   \titem{s2s\_ciphers: Ciphers} \ind{options!s2s\_ciphers} OpenSSL ciphers list
   in the same format accepted by `\verb|openssl ciphers|' command.
+  \titem{s2s\_protocol\_options: ProtocolOpts} \ind{options!s2s\_protocol\_options}
+  List of general options relating to SSL/TLS. These map to \verb|<a href="https://www.openssl.org/docs/ssl/SSL_CTX_set_options.html">OpenSSL's set_options()</a>|.
+  For a full list of options available in ejabberd, \verb|<a href="https://github.com/processone/tls/blob/protocol_options/c_src/options.h">see the source</a>|.
+  The default enitry is: \verb|"no_sslv2"|
   \titem{outgoing\_s2s\_families: [Family, ...]} \ind{options!outgoing\_s2s\_families}
   Specify which address families to try, in what order.
   By default it first tries connecting with IPv4, if that fails it tries using IPv6.
diff --git a/ejabberd.yml.example b/ejabberd.yml.example
index 28f61fdbe..2e744103f 100644
--- a/ejabberd.yml.example
+++ b/ejabberd.yml.example
@@ -86,6 +86,12 @@ listen:
     ##
     ## certfile: "/path/to/ssl.pem"
     ## starttls: true
+    ##
+    ## Custom OpenSSL options
+    ##
+    ## protocol_options:
+    ##   - "no_sslv3"
+    ##   - "no_tlsv1"
     max_stanza_size: 65536
     shaper: c2s_shaper
     access: c2s
@@ -144,6 +150,12 @@ listen:
 ##
 ## s2s_certfile: "/path/to/ssl.pem"
 
+## Custom OpenSSL options
+##
+## s2s_protocol_options:
+##   - "no_sslv3"
+##   - "no_tlsv1"
+
 ##
 ## domain_certfile: Specify a different certificate for each served hostname.
 ##
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 44ad2d56b..33d76b07c 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -244,11 +244,20 @@ init([{SockMod, Socket}, Opts]) ->
 				(_) -> false
 			    end,
 			    Opts),
-    TLSOpts2 = case proplists:get_bool(tls_compression, Opts) of
-                   false -> [compression_none | TLSOpts1];
-                   true -> TLSOpts1
+    TLSOpts2 = case lists:keysearch(protocol_options, 1, Opts) of
+                   {value, {_, O}} ->
+                       [_|ProtocolOptions] = lists:foldl(
+                                    fun(X, Acc) -> X ++ Acc end, [],
+                                    [["|" | binary_to_list(Opt)] || Opt <- O, is_binary(Opt)]
+                                   ),
+                        [{protocol_options, iolist_to_binary(ProtocolOptions)} | TLSOpts1];
+                   _ -> TLSOpts1
                end,
-    TLSOpts = [verify_none | TLSOpts2],
+    TLSOpts3 = case proplists:get_bool(tls_compression, Opts) of
+                   false -> [compression_none | TLSOpts2];
+                   true -> TLSOpts2
+               end,
+    TLSOpts = [verify_none | TLSOpts3],
     IP = peerip(SockMod, Socket),
     %% Check if IP is blacklisted:
     case is_ip_blacklisted(IP) of
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 0759ef5b9..bd2f13a8a 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -181,9 +181,21 @@ init([{SockMod, Socket}, Opts]) ->
                    undefined -> TLSOpts1;
                    Ciphers -> [{ciphers, Ciphers} | TLSOpts1]
                end,
+    TLSOpts3 = case ejabberd_config:get_option(
+                      s2s_protocol_options,
+                      fun (Options) ->
+                              [_|O] = lists:foldl(
+                                           fun(X, Acc) -> X ++ Acc end, [],
+                                           [["|" | binary_to_list(Opt)] || Opt <- Options, is_binary(Opt)]
+                                          ),
+                              iolist_to_binary(O)
+                      end) of
+                   undefined -> TLSOpts2;
+                   ProtocolOpts -> [{protocol_options, ProtocolOpts} | TLSOpts2]
+               end,
     TLSOpts = case proplists:get_bool(tls_compression, Opts) of
-                  false -> [compression_none | TLSOpts2];
-                  true -> TLSOpts2
+                  false -> [compression_none | TLSOpts3];
+                  true -> TLSOpts3
               end,
     Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
     {ok, wait_for_stream,
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index 8e4454d0b..a0a83631d 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -195,13 +195,25 @@ init([From, Server, Type]) ->
                    undefined -> TLSOpts1;
                    Ciphers -> [{ciphers, Ciphers} | TLSOpts1]
                end,
+    TLSOpts3 = case ejabberd_config:get_option(
+                      s2s_protocol_options,
+                      fun (Options) ->
+                              [_|O] = lists:foldl(
+                                           fun(X, Acc) -> X ++ Acc end, [],
+                                           [["|" | binary_to_list(Opt)] || Opt <- Options, is_binary(Opt)]
+                                          ),
+                              iolist_to_binary(O)
+                      end) of
+                   undefined -> TLSOpts2;
+                   ProtocolOpts -> [{protocol_options, ProtocolOpts} | TLSOpts2]
+               end,
     TLSOpts = case ejabberd_config:get_option(
                      {s2s_tls_compression, From},
                      fun(true) -> true;
                         (false) -> false
                      end, true) of
-                  false -> [compression_none | TLSOpts2];
-                  true -> TLSOpts2
+                  false -> [compression_none | TLSOpts3];
+                  true -> TLSOpts3
               end,
     {New, Verify} = case Type of
 		      {new, Key} -> {Key, false};
