summaryrefslogtreecommitdiffstats
path: root/roles/common/files
diff options
context:
space:
mode:
Diffstat (limited to 'roles/common/files')
-rw-r--r--roles/common/files/etc/logcheck/ignore.d.server/strongswan-local19
-rw-r--r--roles/common/files/etc/strongswan.d/charon.conf303
-rw-r--r--roles/common/files/etc/strongswan.d/charon/socket-default.conf20
-rwxr-xr-xroles/common/files/usr/local/sbin/update-firewall.sh102
4 files changed, 374 insertions, 70 deletions
diff --git a/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local b/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local
new file mode 100644
index 0000000..13218b0
--- /dev/null
+++ b/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local
@@ -0,0 +1,19 @@
+# Ansible Managed
+# Do NOT edit this file directly!
+#
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] spawning [[:digit:]]+ worker threads$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] creating acquire job for policy [[:xdigit:].:]{3,39}/[[:digit:]]+(\[\w+(/[[:alnum:]-]+)?\])? === [[:xdigit:].:]{3,39}/[[:digit:]]+(\[\w+(/[[:alnum:]-]+)?\])? with reqid \{[[:digit:]]+\}$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] creating rekey job for ESP CHILD_SA with SPI [[:xdigit:]]{8} and reqid \{[[:digit:]]+\}$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] creating delete job for ESP CHILD_SA with SPI [[:xdigit:]]{8} and reqid \{[[:digit:]]+\}$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] querying SAD entry with SPI [[:xdigit:]]{8} failed: No such process \([[:digit:]]+\)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] initiating IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\] to [[:xdigit:].:]{3,39}$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] [[:xdigit:].:]{3,39} is initiating an IKE_SA$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] establishing CHILD_SA [[:alnum:]._-]+(\{[[:digit:]]+\})?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\] established between [[:xdigit:].:]{3,39}\[[^]\"]+\]\.\.\.[[:xdigit:].:]{3,39}\[[^]]+\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] CHILD_SA [[:alnum:]._-]+\{[[:digit:]]+\} established with SPIs [[:xdigit:]]{8}_i [[:xdigit:]]{8}_o and TS [[:xdigit:].:]{3,39}/[[:digit:]]+ === [[:xdigit:].:]{3,39}/[[:digit:]]+$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] closing CHILD_SA [[:alnum:]._-]+\{[[:digit:]]+\} with SPIs [[:xdigit:]]{8}_i \([[:digit:]]+ bytes\) [[:xdigit:]]{8}_o \([[:digit:]]+ bytes\) and TS [[:xdigit:].:]{3,39}/[[:digit:]]+ === [[:xdigit:].:]{3,39}/[[:digit:]]+$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] reauthenticating IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] deleting IKE_SA after [[:digit:]]+ seconds of CHILD_SA inactivity$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] deleting IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\] between [[:xdigit:].:]{3,39}\[[^]\"]+\]\.\.\.[[:xdigit:].:]{3,39}\[[^]]+\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] IKE_SA deleted$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ vpn: [+-] .* [[:xdigit:].:]{3,39}/[[:digit:]]+ == [[:xdigit:].:]{3,39} -- [[:xdigit:].:]{3,39} == [[:xdigit:].:]{3,39}/[[:digit:]]+$
diff --git a/roles/common/files/etc/strongswan.d/charon.conf b/roles/common/files/etc/strongswan.d/charon.conf
new file mode 100644
index 0000000..17e917a
--- /dev/null
+++ b/roles/common/files/etc/strongswan.d/charon.conf
@@ -0,0 +1,303 @@
+# Options for the charon IKE daemon.
+charon {
+
+ # Accept unencrypted ID and HASH payloads in IKEv1 Main Mode.
+ # accept_unencrypted_mainmode_messages = no
+
+ # Maximum number of half-open IKE_SAs for a single peer IP.
+ # block_threshold = 5
+
+ # Whether relations in validated certificate chains should be cached in
+ # memory.
+ # cert_cache = yes
+
+ # Send Cisco Unity vendor ID payload (IKEv1 only).
+ # cisco_unity = no
+
+ # Close the IKE_SA if setup of the CHILD_SA along with IKE_AUTH failed.
+ # close_ike_on_child_failure = no
+
+ # Number of half-open IKE_SAs that activate the cookie mechanism.
+ # cookie_threshold = 10
+
+ # Use ANSI X9.42 DH exponent size or optimum size matched to cryptographic
+ # strength.
+ # dh_exponent_ansi_x9_42 = yes
+
+ # DNS server assigned to peer via configuration payload (CP).
+ # dns1 =
+
+ # DNS server assigned to peer via configuration payload (CP).
+ # dns2 =
+
+ # Enable Denial of Service protection using cookies and aggressiveness
+ # checks.
+ # dos_protection = yes
+
+ # Compliance with the errata for RFC 4753.
+ # ecp_x_coordinate_only = yes
+
+ # Free objects during authentication (might conflict with plugins).
+ # flush_auth_cfg = no
+
+ # Maximum size (complete IP datagram size in bytes) of a sent IKE fragment
+ # when using proprietary IKEv1 or standardized IKEv2 fragmentation (0 for
+ # address family specific default values). If specified this limit is
+ # used for both IPv4 and IPv6.
+ # fragment_size = 0
+
+ # Name of the group the daemon changes to after startup.
+ # group =
+
+ # Timeout in seconds for connecting IKE_SAs (also see IKE_SA_INIT DROPPING).
+ # half_open_timeout = 30
+
+ # Enable hash and URL support.
+ # hash_and_url = no
+
+ # Allow IKEv1 Aggressive Mode with pre-shared keys as responder.
+ # i_dont_care_about_security_and_use_aggressive_mode_psk = no
+
+ # A space-separated list of routing tables to be excluded from route
+ # lookups.
+ # ignore_routing_tables =
+
+ # Maximum number of IKE_SAs that can be established at the same time before
+ # new connection attempts are blocked.
+ # ikesa_limit = 0
+
+ # Number of exclusively locked segments in the hash table.
+ # ikesa_table_segments = 1
+
+ # Size of the IKE_SA hash table.
+ # ikesa_table_size = 1
+
+ # Whether to close IKE_SA if the only CHILD_SA closed due to inactivity.
+ inactivity_close_ike = yes
+
+ # Limit new connections based on the current number of half open IKE_SAs,
+ # see IKE_SA_INIT DROPPING in strongswan.conf(5).
+ # init_limit_half_open = 0
+
+ # Limit new connections based on the number of queued jobs.
+ # init_limit_job_load = 0
+
+ # Causes charon daemon to ignore IKE initiation requests.
+ # initiator_only = no
+
+ # Install routes into a separate routing table for established IPsec
+ # tunnels.
+ install_routes = no
+
+ # Install virtual IP addresses.
+ install_virtual_ip = no
+
+ # The name of the interface on which virtual IP addresses should be
+ # installed.
+ # install_virtual_ip_on =
+
+ # Check daemon, libstrongswan and plugin integrity at startup.
+ # integrity_test = no
+
+ # A comma-separated list of network interfaces that should be ignored, if
+ # interfaces_use is specified this option has no effect.
+ # interfaces_ignore =
+
+ # A comma-separated list of network interfaces that should be used by
+ # charon. All other interfaces are ignored.
+ # interfaces_use =
+
+ # NAT keep alive interval.
+ # keep_alive = 20s
+
+ # Plugins to load in the IKE daemon charon.
+ # load =
+
+ # Determine plugins to load via each plugin's load option.
+ # load_modular = no
+
+ # Maximum packet size accepted by charon.
+ # max_packet = 10000
+
+ # Enable multiple authentication exchanges (RFC 4739).
+ # multiple_authentication = yes
+
+ # WINS servers assigned to peer via configuration payload (CP).
+ # nbns1 =
+
+ # WINS servers assigned to peer via configuration payload (CP).
+ # nbns2 =
+
+ # UDP port used locally. If set to 0 a random port will be allocated.
+ # port = 500
+
+ # UDP port used locally in case of NAT-T. If set to 0 a random port will be
+ # allocated. Has to be different from charon.port, otherwise a random port
+ # will be allocated.
+ # port_nat_t = 4500
+
+ # By default public IPv6 addresses are preferred over temporary ones (RFC
+ # 4941), to make connections more stable. Enable this option to reverse
+ # this.
+ # prefer_temporary_addrs = no
+
+ # Process RTM_NEWROUTE and RTM_DELROUTE events.
+ # process_route = yes
+
+ # Delay in ms for receiving packets, to simulate larger RTT.
+ # receive_delay = 0
+
+ # Delay request messages.
+ # receive_delay_request = yes
+
+ # Delay response messages.
+ # receive_delay_response = yes
+
+ # Specific IKEv2 message type to delay, 0 for any.
+ # receive_delay_type = 0
+
+ # Size of the AH/ESP replay window, in packets.
+ # replay_window = 32
+
+ # Base to use for calculating exponential back off, see IKEv2 RETRANSMISSION
+ # in strongswan.conf(5).
+ # retransmit_base = 1.8
+
+ # Timeout in seconds before sending first retransmit.
+ # retransmit_timeout = 4.0
+
+ # Number of times to retransmit a packet before giving up.
+ # retransmit_tries = 5
+
+ # Interval to use when retrying to initiate an IKE_SA (e.g. if DNS
+ # resolution failed), 0 to disable retries.
+ # retry_initiate_interval = 0
+
+ # Initiate CHILD_SA within existing IKE_SAs.
+ # reuse_ikesa = yes
+
+ # Numerical routing table to install routes to.
+ # routing_table =
+
+ # Priority of the routing table.
+ # routing_table_prio =
+
+ # Delay in ms for sending packets, to simulate larger RTT.
+ # send_delay = 0
+
+ # Delay request messages.
+ # send_delay_request = yes
+
+ # Delay response messages.
+ # send_delay_response = yes
+
+ # Specific IKEv2 message type to delay, 0 for any.
+ # send_delay_type = 0
+
+ # Send strongSwan vendor ID payload
+ # send_vendor_id = no
+
+ # Number of worker threads in charon.
+ # threads = 16
+
+ # Name of the user the daemon changes to after startup.
+ # user =
+
+ crypto_test {
+
+ # Benchmark crypto algorithms and order them by efficiency.
+ # bench = no
+
+ # Buffer size used for crypto benchmark.
+ # bench_size = 1024
+
+ # Number of iterations to test each algorithm.
+ # bench_time = 50
+
+ # Test crypto algorithms during registration (requires test vectors
+ # provided by the test-vectors plugin).
+ # on_add = no
+
+ # Test crypto algorithms on each crypto primitive instantiation.
+ # on_create = no
+
+ # Strictly require at least one test vector to enable an algorithm.
+ # required = no
+
+ # Whether to test RNG with TRUE quality; requires a lot of entropy.
+ # rng_true = no
+
+ }
+
+ host_resolver {
+
+ # Maximum number of concurrent resolver threads (they are terminated if
+ # unused).
+ # max_threads = 3
+
+ # Minimum number of resolver threads to keep around.
+ # min_threads = 0
+
+ }
+
+ leak_detective {
+
+ # Includes source file names and line numbers in leak detective output.
+ # detailed = yes
+
+ # Threshold in bytes for leaks to be reported (0 to report all).
+ # usage_threshold = 10240
+
+ # Threshold in number of allocations for leaks to be reported (0 to
+ # report all).
+ # usage_threshold_count = 0
+
+ }
+
+ processor {
+
+ # Section to configure the number of reserved threads per priority class
+ # see JOB PRIORITY MANAGEMENT in strongswan.conf(5).
+ priority_threads {
+
+ }
+
+ }
+
+ # Section containing a list of scripts (name = path) that are executed when
+ # the daemon is started.
+ start-scripts {
+
+ }
+
+ # Section containing a list of scripts (name = path) that are executed when
+ # the daemon is terminated.
+ stop-scripts {
+
+ }
+
+ tls {
+
+ # List of TLS encryption ciphers.
+ # cipher =
+
+ # List of TLS key exchange methods.
+ # key_exchange =
+
+ # List of TLS MAC algorithms.
+ # mac =
+
+ # List of TLS cipher suites.
+ # suites =
+
+ }
+
+ x509 {
+
+ # Discard certificates with unsupported or unknown critical extensions.
+ # enforce_critical = yes
+
+ }
+
+}
+
diff --git a/roles/common/files/etc/strongswan.d/charon/socket-default.conf b/roles/common/files/etc/strongswan.d/charon/socket-default.conf
new file mode 100644
index 0000000..1bc20f1
--- /dev/null
+++ b/roles/common/files/etc/strongswan.d/charon/socket-default.conf
@@ -0,0 +1,20 @@
+socket-default {
+
+ # Firewall mark to set on outbound packets.
+ # fwmark =
+
+ # Whether to load the plugin. Can also be an integer to increase the
+ # priority of this plugin.
+ load = yes
+
+ # Set source address on outbound packets, if possible.
+ # set_source = yes
+
+ # Listen on IPv4, if possible.
+ # use_ipv4 = yes
+
+ # Listen on IPv6, if possible.
+ use_ipv6 = no
+
+}
+
diff --git a/roles/common/files/usr/local/sbin/update-firewall.sh b/roles/common/files/usr/local/sbin/update-firewall.sh
index f25f507..065bae2 100755
--- a/roles/common/files/usr/local/sbin/update-firewall.sh
+++ b/roles/common/files/usr/local/sbin/update-firewall.sh
@@ -40,8 +40,12 @@ check=0
verbose=0
addrfam=
-secmark=0xA99 # must match that in /etc/network/if-up.d/ipsec
-secproto=esp # must match /etc/ipsec.conf; ESP is the default (vs AH/IPComp)
+secproto=esp # must match /etc/ipsec.conf; ESP is the default (vs AH/IPComp)
+if [ -x /usr/sbin/ipsec ] && /usr/sbin/ipsec status >/dev/null; then
+ ipsec=y
+else
+ ipsec=n
+fi
fail2ban_re='^(\[[0-9]+:[0-9]+\]\s+)?-A fail2ban-\S'
IPSec_re=" -m policy --dir (in|out) --pol ipsec --reqid [0-9]+ --proto $secproto -j ACCEPT$"
@@ -152,21 +156,9 @@ run() {
tables[$f]=filter
# The default interface associated with this address.
- local if=$( /bin/ip -$f route show to default scope global \
+ local if=$( /bin/ip -$f -o route show to default scope global \
| sed -nr '/^default via \S+ dev (\S+).*/ {s//\1/p;q}' )
- # The virtual interface reserved for IPSec.
- local ifsec=$( /bin/ip -o -$f link show \
- | sed -nr "/^[0-9]+:\s+(sec[0-9]+)@$if:\s.*/ {s//\1/p;q}" )
-
- # The (host-scoped) IP reserved for IPSec.
- local ipsec=
- if [ "$ifsec" -a $f = 4 ]; then
- tables[$f]='mangle nat filter'
- ipsec=$( /bin/ip -$f address show dev "$ifsec" scope host \
- | sed -nr '/^\s+inet\s(\S+).*/ {s//\1/p;q}' )
- fi
-
# Store the old (current) ruleset
local old=$(mktemp --tmpdir current-rules.v$f.XXXXXX) \
new=$(mktemp --tmpdir new-rules.v$f.XXXXXX)
@@ -203,8 +195,9 @@ run() {
grep -E -- "$fail2ban_re" "$old" || true
fi >> "$new"
- if [ "$ipsec" ]; then
- # (Host-to-host) IPSec tunnels come first. TODO: test IPSec with IPv6.
+ if [ "$f" = 4 -a "$ipsec" = y ]; then
+ # Our IPSec tunnels are IPv4 only.
+ # (Host-to-host) IPSec tunnels come first.
grep -E -- "$IPSec_re" "$old" >> "$new" || true
# Allow any IPsec $secproto protocol packets to be sent and received.
@@ -219,15 +212,24 @@ run() {
# http://baldric.net/loose-iptables-firewall-for-servers/
local ip
- if [ "$f" = 4 ]; then
+ if [ "$f" = 4 -a "$ipsec" = y ]; then
# Private-use networks (RFC 1918) and link local (RFC 3927)
- local MyNetwork=$( /bin/ip -4 address show dev $if scope global \
- | sed -nr 's/^\s+inet\s(\S+).*/\1/p')
+ local MyIPSec="$( /bin/ip -4 -o route show table 220 dev $if | sed 's/\s.*//' )"
+ local MyNetwork="$( /bin/ip -4 -o address show dev $if scope global \
+ | sed -nr "s/^[0-9]+:\s+$if\s+inet\s(\S+).*/\1/p" \
+ | while read ip; do
+ for ips in $MyIPSec; do
+ [ "$ips" = "$(/usr/bin/netmask -nc "$ip" "$ips" | sed 's/^ *//')" ] || echo "$ip"
+ done
+ done
+ )"
[ "$MyNetwork" ] && \
for ip in 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 169.254.0.0/16; do
# Don't lock us out if we are behind a NAT ;-)
- [ "$ip" = "$(/usr/bin/netmask -nc $ip $MyNetwork | sed 's/ //g')" ] \
- || iptables -A INPUT -i $if -s "$ip" -j DROP
+ for myip in $MyNetwork; do
+ [ "$ip" = "$(/usr/bin/netmask -nc "$ip" "$myip" | sed 's/^ *//')" ] \
+ || iptables -A INPUT -i $if -s "$ip" -j DROP
+ done
done
# Other martian packets: "This" network, multicast, broadcast (RFCs
@@ -259,14 +261,14 @@ run() {
local localhost=$(inet46 $f '127.0.0.1/8' '::1/128')
iptables -A INPUT -i lo -s "$localhost" -d "$localhost" -j ACCEPT
iptables -A OUTPUT -o lo -s "$localhost" -d "$localhost" -j ACCEPT
-
- if [ "$ipsec" ]; then
- # ACCEPT any, *IPSec* traffic destinating to the non-routable
- # $ipsec. Also ACCEPT all traffic originating from $ipsec, as
- # it is MASQUERADE'd.
- iptables -A INPUT -d "$ipsec" -i $if -m policy --dir in \
- --pol ipsec --proto $secproto -j ACCEPT
- iptables -A OUTPUT -m mark --mark "$secmark" -o $if -j ACCEPT
+ if [ "$f" = 4 -a "$ipsec" = y ]; then
+ # Allow local access to our virtual IP
+ /bin/ip -4 -o route show table 220 dev $if \
+ | sed -nr 's/.*\ssrc\s+([[:digit:].]{7,15})(\s.*)?/\1/p' \
+ | while read ipsec; do
+ iptables -A INPUT -i lo -s "$ipsec" -d "$ipsec" -j ACCEPT
+ iptables -A OUTPUT -o lo -s "$ipsec" -d "$ipsec" -j ACCEPT
+ done
fi
# Prepare fail2ban. We make fail2ban insert its rules in a
@@ -330,46 +332,6 @@ run() {
########################################################################
commit
- if [ "$ipsec" ]; then
- # DNAT the IPSec paquets to $ipsec after decapsulation, and SNAT
- # them before encapsulation. We need to do the NAT'ing before
- # packets enter the IPSec stack because they are signed
- # afterwards, and NAT'ing would mess up the signature.
- ipt-chains mangle PREROUTING:ACCEPT INPUT:ACCEPT \
- FORWARD:DROP \
- OUTPUT:ACCEPT POSTROUTING:ACCEPT
-
- # Packets which destination is $ipsec *must* be associated with
- # an IPSec policy.
- iptables -A INPUT -d "$ipsec" -i $if -m policy --dir in \
- --pol ipsec --proto $secproto -j ACCEPT
- iptables -A INPUT -d "$ipsec" -i $if -j DROP
-
- # Packets originating from our (non-routable) $ipsec are marked;
- # if there is no xfrm lookup (i.e., no matching IPSec
- # association), the packet will retain its mark and be null
- # routed later on. Otherwise, the packet is re-queued unmarked.
- iptables -A OUTPUT -o $if -j MARK --set-mark 0x0
- iptables -A OUTPUT -s "$ipsec" -o $if -m policy --dir out \
- --pol none -j MARK --set-mark $secmark
- commit
-
- ipt-chains nat PREROUTING:ACCEPT INPUT:ACCEPT \
- OUTPUT:ACCEPT POSTROUTING:ACCEPT
-
- # DNAT all marked packets after decapsulation.
- iptables -A PREROUTING \! -d "$ipsec" -i $if -m policy --dir in \
- --pol ipsec --proto $secproto -j DNAT --to "${ipsec%/*}"
-
- # Packets originating from our IPSec are SNAT'ed (MASQUERADE).
- # (And null-routed later on unless there is an xfrm
- # association.)
- iptables -A POSTROUTING -m mark --mark $secmark -o $if -j MASQUERADE
- commit
- fi
-
- ########################################################################
-
local rv1=0 rv2=0 persistent=/etc/iptables/rules.v$f
local oldz=$(mktemp --tmpdir current-rules.v$f.XXXXXX)