@ -19,7 +19,7 @@ short_description: Manage HTTPD related settings on BIG-IP
description :
- Manages HTTPD related settings on the BIG - IP . These settings are interesting
to change when you want to set GUI timeouts and other TMUI related settings .
version_added : " 2.5 "
version_added : 2.5
options :
allow :
description :
@ -64,6 +64,31 @@ options:
ssl_port :
description :
- The HTTPS port to listen on .
ssl_cipher_suite :
description :
- Specifies the ciphers that the system uses .
- The values in the suite are separated by colons ( : ) .
- Can be specified in either a string or list form . The list form is the
recommended way to provide the cipher suite . See examples for usage .
- Use the value C ( default ) to set the cipher suite to the system default .
This value is equivalent to specifying a list of C ( ECDHE - RSA - AES128 - GCM - SHA256 ,
ECDHE - RSA - AES256 - GCM - SHA384 , ECDHE - RSA - AES128 - SHA , ECDHE - RSA - AES256 - SHA ,
ECDHE - RSA - AES128 - SHA256 , ECDHE - RSA - AES256 - SHA384 , ECDHE - ECDSA - AES128 - GCM - SHA256 ,
ECDHE - ECDSA - AES256 - GCM - SHA384 , ECDHE - ECDSA - AES128 - SHA , ECDHE - ECDSA - AES256 - SHA ,
ECDHE - ECDSA - AES128 - SHA256 , ECDHE - ECDSA - AES256 - SHA384 , AES128 - GCM - SHA256 ,
AES256 - GCM - SHA384 , AES128 - SHA , AES256 - SHA , AES128 - SHA256 , AES256 - SHA256 ,
ECDHE - RSA - DES - CBC3 - SHA , ECDHE - ECDSA - DES - CBC3 - SHA , DES - CBC3 - SHA ) .
version_added : 2.6
ssl_protocols :
description :
- The list of SSL protocols to accept on the management console .
- A space - separated list of tokens in the format accepted by the Apache
mod_ssl SSLProtocol directive .
- Can be specified in either a string or list form . The list form is the
recommended way to provide the cipher suite . See examples for usage .
- Use the value C ( default ) to set the SSL protocols to the system default .
This value is equivalent to specifying a list of C ( all , - SSLv2 , - SSLv3 ) .
version_added : 2.6
notes :
- Requires the requests Python package on the host . This is as easy as
C ( pip install requests ) .
@ -99,6 +124,45 @@ EXAMPLES = r'''
server : lb . mydomain . com
user : admin
delegate_to : localhost
- name : Set SSL cipher suite by list
bigip_device_httpd :
password : secret
server : lb . mydomain . com
user : admin
ssl_cipher_suite :
- ECDHE - RSA - AES128 - GCM - SHA256
- ECDHE - RSA - AES256 - GCM - SHA384
- ECDHE - RSA - AES128 - SHA
- AES256 - SHA256
delegate_to : localhost
- name : Set SSL cipher suite by string
bigip_device_httpd :
password : secret
server : lb . mydomain . com
user : admin
ssl_cipher_suite : ECDHE - RSA - AES128 - GCM - SHA256 : ECDHE - RSA - AES256 - GCM - SHA384 : ECDHE - RSA - AES128 - SHA : AES256 - SHA256
delegate_to : localhost
- name : Set SSL protocols by list
bigip_device_httpd :
password : secret
server : lb . mydomain . com
user : admin
ssl_protocols :
- all
- - SSLv2
- - SSLv3
delegate_to : localhost
- name : Set SSL protocols by string
bigip_device_httpd :
password : secret
server : lb . mydomain . com
user : admin
ssl_cipher_suite : all - SSLv2 - SSLv3
delegate_to : localhost
'''
RETURN = r '''
@ -152,36 +216,40 @@ ssl_port:
returned : changed
type : int
sample : 10443
ssl_cipher_suite :
description : The new ciphers that the system uses .
returned : changed
type : string
sample : ECDHE - RSA - AES256 - GCM - SHA384 : ECDHE - RSA - AES128 - SHA
ssl_protocols :
description : The new list of SSL protocols to accept on the management console .
returned : changed
type : string
sample : all - SSLv2 - SSLv3
'''
import time
from ansible . module_utils . basic import AnsibleModule
HAS_DEVEL_IMPORTS = False
from ansible . module_utils . six import string_types
try :
# Sideband repository used for dev
from library . module_utils . network . f5 . bigip import HAS_F5SDK
from library . module_utils . network . f5 . bigip import F5Client
from library . module_utils . network . f5 . common import F5ModuleError
from library . module_utils . network . f5 . common import AnsibleF5Parameters
from library . module_utils . network . f5 . common import cleanup_tokens
from library . module_utils . network . f5 . common import fqdn_name
from library . module_utils . network . f5 . common import f5_argument_spec
try :
from library . module_utils . network . f5 . common import iControlUnexpectedHTTPError
except ImportError :
HAS_F5SDK = False
HAS_DEVEL_IMPORTS = True
except ImportError :
# Upstream Ansible
from ansible . module_utils . network . f5 . bigip import HAS_F5SDK
from ansible . module_utils . network . f5 . bigip import F5Client
from ansible . module_utils . network . f5 . common import F5ModuleError
from ansible . module_utils . network . f5 . common import AnsibleF5Parameters
from ansible . module_utils . network . f5 . common import cleanup_tokens
from ansible . module_utils . network . f5 . common import fqdn_name
from ansible . module_utils . network . f5 . common import f5_argument_spec
try :
from ansible . module_utils . network . f5 . common import iControlUnexpectedHTTPError
@ -206,29 +274,55 @@ class Parameters(AnsibleF5Parameters):
' logLevel ' : ' log_level ' ,
' maxClients ' : ' max_clients ' ,
' redirectHttpToHttps ' : ' redirect_http_to_https ' ,
' sslPort ' : ' ssl_port '
' sslPort ' : ' ssl_port ' ,
' sslCiphersuite ' : ' ssl_cipher_suite ' ,
' sslProtocol ' : ' ssl_protocols '
}
api_attributes = [
' authPamIdleTimeout ' , ' authPamValidateIp ' , ' authName ' , ' authPamDashboardTimeout ' ,
' fastcgiTimeout ' , ' hostnameLookup ' , ' logLevel ' , ' maxClients ' , ' sslPort ' ,
' redirectHttpToHttps ' , ' allow '
' redirectHttpToHttps ' , ' allow ' , ' sslCiphersuite ' , ' sslProtocol '
]
returnables = [
' auth_pam_idle_timeout ' , ' auth_pam_validate_ip ' , ' auth_name ' ,
' auth_pam_dashboard_timeout ' , ' fast_cgi_timeout ' , ' hostname_lookup ' ,
' log_level ' , ' max_clients ' , ' redirect_http_to_https ' , ' ssl_port ' ,
' allow '
' allow ' , ' ssl_cipher_suite ' , ' ssl_protocols '
]
updatables = [
' auth_pam_idle_timeout ' , ' auth_pam_validate_ip ' , ' auth_name ' ,
' auth_pam_dashboard_timeout ' , ' fast_cgi_timeout ' , ' hostname_lookup ' ,
' log_level ' , ' max_clients ' , ' redirect_http_to_https ' , ' ssl_port ' ,
' allow '
' allow ' , ' ssl_cipher_suite ' , ' ssl_protocols '
]
_ciphers = " ECDHE-RSA-AES128-GCM-SHA256: " \
" ECDHE-RSA-AES256-GCM-SHA384: " \
" ECDHE-RSA-AES128-SHA: " \
" ECDHE-RSA-AES256-SHA: " \
" ECDHE-RSA-AES128-SHA256: " \
" ECDHE-RSA-AES256-SHA384: " \
" ECDHE-ECDSA-AES128-GCM-SHA256: " \
" ECDHE-ECDSA-AES256-GCM-SHA384: " \
" ECDHE-ECDSA-AES128-SHA: " \
" ECDHE-ECDSA-AES256-SHA: " \
" ECDHE-ECDSA-AES128-SHA256: " \
" ECDHE-ECDSA-AES256-SHA384: " \
" AES128-GCM-SHA256: " \
" AES256-GCM-SHA384: " \
" AES128-SHA: " \
" AES256-SHA: " \
" AES128-SHA256: " \
" AES256-SHA256: " \
" ECDHE-RSA-DES-CBC3-SHA: " \
" ECDHE-ECDSA-DES-CBC3-SHA: " \
" DES-CBC3-SHA "
_protocols = ' all -SSLv2 -SSLv3 '
@property
def auth_pam_idle_timeout ( self ) :
if self . _values [ ' auth_pam_idle_timeout ' ] is None :
@ -300,6 +394,46 @@ class ModuleParameters(Parameters):
result = sorted ( result )
return result
@property
def ssl_cipher_suite ( self ) :
if self . _values [ ' ssl_cipher_suite ' ] is None :
return None
if isinstance ( self . _values [ ' ssl_cipher_suite ' ] , string_types ) :
ciphers = self . _values [ ' ssl_cipher_suite ' ] . strip ( )
else :
ciphers = self . _values [ ' ssl_cipher_suite ' ]
if not ciphers :
raise F5ModuleError (
" ssl_cipher_suite may not be set to ' none ' "
)
if ciphers == ' default ' :
ciphers = ' : ' . join ( sorted ( Parameters . _ciphers . split ( ' : ' ) ) )
elif isinstance ( self . _values [ ' ssl_cipher_suite ' ] , string_types ) :
ciphers = ' : ' . join ( sorted ( ciphers . split ( ' : ' ) ) )
else :
ciphers = ' : ' . join ( sorted ( ciphers ) )
return ciphers
@property
def ssl_protocols ( self ) :
if self . _values [ ' ssl_protocols ' ] is None :
return None
if isinstance ( self . _values [ ' ssl_protocols ' ] , string_types ) :
protocols = self . _values [ ' ssl_protocols ' ] . strip ( )
else :
protocols = self . _values [ ' ssl_protocols ' ]
if not protocols :
raise F5ModuleError (
" ssl_protocols may not be set to ' none ' "
)
if protocols == ' default ' :
protocols = ' ' . join ( sorted ( Parameters . _protocols . split ( ' ' ) ) )
elif isinstance ( protocols , string_types ) :
protocols = ' ' . join ( sorted ( protocols . split ( ' ' ) ) )
else :
protocols = ' ' . join ( sorted ( protocols ) )
return protocols
class ApiParameters ( Parameters ) :
@property
@ -331,7 +465,21 @@ class UsableChanges(Changes):
class ReportableChanges ( Changes ) :
pass
@property
def ssl_cipher_suite ( self ) :
default = ' : ' . join ( sorted ( Parameters . _ciphers . split ( ' : ' ) ) )
if self . _values [ ' ssl_cipher_suite ' ] == default :
return ' default '
else :
return self . _values [ ' ssl_cipher_suite ' ]
@property
def ssl_protocols ( self ) :
default = ' ' . join ( sorted ( Parameters . _protocols . split ( ' ' ) ) )
if self . _values [ ' ssl_protocols ' ] == default :
return ' default '
else :
return self . _values [ ' ssl_protocols ' ]
class Difference ( object ) :
@ -449,7 +597,6 @@ class ModuleManager(object):
def update_on_device ( self ) :
params = self . changes . api_params ( )
resource = self . client . api . tm . sys . httpd . load ( )
try :
resource . modify ( * * params )
return True
@ -504,7 +651,9 @@ class ArgumentSpec(object):
) ,
redirect_http_to_https = dict (
type = ' bool '
)
) ,
ssl_cipher_suite = dict ( type = ' raw ' ) ,
ssl_protocols = dict ( type = ' raw ' )
)
self . argument_spec = { }
self . argument_spec . update ( f5_argument_spec )