for group, ike_conf in ipsec['ike_group'].items():
if 'proposal' in ike_conf:
ciphers = []
for i in ike_conf['proposal']:
proposal = ike_conf['proposal'][i]
enc = proposal['encryption'] if 'encryption' in proposal else None
hash = proposal['hash'] if 'hash' in proposal else None
pfs = ('dh-group' + proposal['dh_group']) if 'dh_group' in proposal else default_pfs
if not default_ike_pfs:
default_ike_pfs = pfs
if enc and hash:
ciphers.append(f"{enc}-{hash}-{pfs_translate[pfs]}" if pfs else f"{enc}-{hash}")
ike_ciphers[group] = ','.join(ciphers) + '!'
if 'esp_group' in ipsec:
for group, esp_conf in ipsec['esp_group'].items():
pfs = esp_conf['pfs'] if 'pfs' in esp_conf else 'enable'
if pfs == 'disable':
pfs = None
if pfs == 'enable':
pfs = default_ike_pfs
-
+
if 'proposal' in esp_conf:
ciphers = []
for i in esp_conf['proposal']:
proposal = esp_conf['proposal'][i]
enc = proposal['encryption'] if 'encryption' in proposal else None
hash = proposal['hash'] if 'hash' in proposal else None
if enc and hash:
ciphers.append(f"{enc}-{hash}-{pfs_translate[pfs]}" if pfs else f"{enc}-{hash}")
esp_ciphers[group] = ','.join(ciphers) + '!'
return ipsec
def verify(ipsec):
if not ipsec:
return None
if 'profile' in ipsec:
for profile, profile_conf in ipsec['profile'].items():
if 'esp_group' in profile_conf:
if 'esp_group' not in ipsec or profile_conf['esp_group'] not in ipsec['esp_group']:
raise ConfigError(f"Invalid esp-group on {profile} profile")
else:
raise ConfigError(f"Missing esp-group on {profile} profile")
if 'ike_group' in profile_conf:
if 'ike_group' not in ipsec or profile_conf['ike_group'] not in ipsec['ike_group']:
raise ConfigError(f"Invalid ike-group on {profile} profile")
else:
raise ConfigError(f"Missing ike-group on {profile} profile")
if 'authentication' not in profile_conf:
raise ConfigError(f"Missing authentication on {profile} profile")
if 'site_to_site' in ipsec and 'peer' in ipsec['site_to_site']:
for peer, peer_conf in ipsec['site_to_site']['peer'].items():
has_default_esp = False
if 'default_esp_group' in peer_conf:
has_default_esp = True
if 'esp_group' not in ipsec or peer_conf['default_esp_group'] not in ipsec['esp_group']:
raise ConfigError(f"Invalid esp-group on site-to-site peer {peer}")
if 'ike_group' in peer_conf:
if 'ike_group' not in ipsec or peer_conf['ike_group'] not in ipsec['ike_group']:
raise ConfigError(f"Invalid ike-group on site-to-site peer {peer}")
else:
raise ConfigError(f"Missing ike-group on site-to-site peer {peer}")
if 'authentication' not in peer_conf or 'mode' not in peer_conf['authentication']:
raise ConfigError(f"Missing authentication on site-to-site peer {peer}")
if peer_conf['authentication']['mode'] == 'x509':
if 'x509' not in peer_conf['authentication']:
raise ConfigError(f"Missing x509 settings on site-to-site peer {peer}")
if 'key' not in peer_conf['authentication']['x509'] or 'ca_cert_file' not in peer_conf['authentication']['x509'] or 'cert_file' not in peer_conf['authentication']['x509']:
raise ConfigError(f"Missing x509 settings on site-to-site peer {peer}")
if 'file' not in peer_conf['authentication']['x509']['key']:
raise ConfigError(f"Missing x509 settings on site-to-site peer {peer}")
for key in ['ca_cert_file', 'cert_file', 'crl_file']:
if key in peer_conf['authentication']['x509']:
path = peer_conf['authentication']['x509'][key]
if not os.path.exists(path if path.startswith(X509_PATH) else (X509_PATH + path)):
raise ConfigError(f"File not found for {key} on site-to-site peer {peer}")
if not os.path.exists(key_path if key_path.startswith(X509_PATH) else (X509_PATH + key_path)):
raise ConfigError(f"Private key not found on site-to-site peer {peer}")
if peer_conf['authentication']['mode'] == 'rsa':
if not verify_rsa_local_key():
raise ConfigError(f"Invalid key on rsa-keys local-key")
if 'rsa_key_name' not in peer_conf['authentication']:
raise ConfigError(f"Missing rsa-key-name on site-to-site peer {peer}")
if not verify_rsa_key(peer_conf['authentication']['rsa_key_name']):
raise ConfigError(f"Invalid rsa-key-name on site-to-site peer {peer}")
if 'local_address' not in peer_conf and 'dhcp_interface' not in peer_conf:
raise ConfigError(f"Missing local-address or dhcp-interface on site-to-site peer {peer}")
if 'dhcp_interface' in peer_conf:
dhcp_interface = peer_conf['dhcp_interface']
if not os.path.exists(f'{DHCP_BASE}_{dhcp_interface}.conf'):
raise ConfigError(f"Invalid dhcp-interface on site-to-site peer {peer}")
if 'vti' in peer_conf:
if 'local_address' in peer_conf and 'dhcp_interface' in peer_conf:
raise ConfigError(f"A single local-address or dhcp-interface is required when using VTI on site-to-site peer {peer}")
if 'bind' in peer_conf['vti']:
vti_interface = peer_conf['vti']['bind']
if not get_vti_interface(vti_interface):
raise ConfigError(f'Invalid VTI interface on site-to-site peer {peer}')
if 'vti' not in peer_conf and 'tunnel' not in peer_conf:
raise ConfigError(f"No vti or tunnels specified on site-to-site peer {peer}")
if 'tunnel' in peer_conf:
for tunnel, tunnel_conf in peer_conf['tunnel'].items():
if 'esp_group' not in tunnel_conf and not has_default_esp:
raise ConfigError(f"Missing esp-group on tunnel {tunnel} for site-to-site peer {peer}")
esp_group_name = tunnel_conf['esp_group'] if 'esp_group' in tunnel_conf else peer_conf['default_esp_group']
if esp_group_name not in ipsec['esp_group']:
raise ConfigError(f"Invalid esp-group on tunnel {tunnel} for site-to-site peer {peer}")
esp_group = ipsec['esp_group'][esp_group_name]
if 'mode' in esp_group and esp_group['mode'] == 'transport':
if 'protocol' in tunnel_conf and ((peer in ['any', '0.0.0.0']) or ('local_address' not in peer_conf or peer_conf['local_address'] in ['any', '0.0.0.0'])):
raise ConfigError(f"Fixed local-address or peer required when a protocol is defined with ESP transport mode on tunnel {tunnel} for site-to-site peer {peer}")
if ('local' in tunnel_conf and 'prefix' in tunnel_conf['local']) or ('remote' in tunnel_conf and 'prefix' in tunnel_conf['remote']):
raise ConfigError(f"Local/remote prefix cannot be used with ESP transport mode on tunnel {tunnel} for site-to-site peer {peer}")