PKG_NAME:=libreswan
PKG_VERSION:=4.12
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://download.libreswan.org/
include $(INCLUDE_DIR)/package.mk
-define Package/libreswan/Default
- TITLE:=Libreswan
- URL:=https://libreswan.org/
-endef
-
-define Package/libreswan/Default/description
- Libreswan is a free software implementation of the most widely supported and
- standardized VPN protocol based on ("IPsec") and the Internet Key Exchange
- ("IKE"). These standards are produced and maintained by the Internet
- Engineering Task Force ("IETF").
-endef
-
-define Package/libreswan
-$(call Package/libreswan/Default)
+define Package/libreswan/default
SUBMENU:=VPN
SECTION:=net
CATEGORY:=Network
- DEPENDS:= +IPV6:kmod-ip6-vti +IPV6:kmod-ipsec6 +ip-full +iptables-mod-ipsec \
- +kmod-crypto-aead +kmod-crypto-authenc +kmod-crypto-gcm \
- +kmod-crypto-hash +kmod-crypto-rng +kmod-ip-vti +kmod-ipsec \
- +kmod-ipsec4 +kmod-ipt-ipsec +kmod-xfrm-interface +libevent2 +libevent2-pthreads \
- +libldns +librt +libunbound +nss-utils +nspr +libcap-ng
+ TITLE:=Libreswan
+ URL:=https://libreswan.org/
PROVIDES:=openswan
CONFLICTS:=strongswan
- TITLE+= IPsec Server
+endef
+
+define Package/libreswan
+ $(Package/libreswan/default)
+ DEPENDS:= \
+ +kmod-ip-vti +IPV6:kmod-ip6-vti \
+ +kmod-ipsec +kmod-ipsec4 +IPV6:kmod-ipsec6 \
+ +ip-full +kmod-xfrm-interface \
+ +libevent2 +libevent2-pthreads \
+ +libldns +librt +libunbound +nss-utils +nspr +libcap-ng \
+ +kmod-crypto-acompress \
+ +kmod-crypto-aead \
+ +kmod-crypto-authenc \
+ +kmod-crypto-arc4 \
+ +kmod-crypto-cbc \
+ +kmod-crypto-ccm \
+ +kmod-crypto-chacha20poly1305 \
+ +kmod-crypto-cmac \
+ +kmod-crypto-ctr \
+ +kmod-crypto-cts \
+ +kmod-crypto-des \
+ +kmod-crypto-ecb \
+ +kmod-crypto-ecdh \
+ +kmod-crypto-gcm \
+ +kmod-crypto-ghash \
+ +kmod-crypto-hash \
+ +kmod-crypto-hmac \
+ +kmod-crypto-md4 \
+ +kmod-crypto-md5 \
+ +kmod-crypto-null \
+ +kmod-crypto-pcbc \
+ +kmod-crypto-sha1 \
+ +kmod-crypto-sha256 \
+ +kmod-crypto-sha512 \
+ +kmod-crypto-xcbc \
+ +kmod-crypto-rng
endef
define Package/libreswan/description
-$(call Package/libreswan/Default/description)
- Libreswan is a free software implementation of the most widely supported and
- standardized VPN protocol based on ("IPsec") and the Internet Key Exchange
- ("IKE"). These standards are produced and maintained by the Internet
- Engineering Task Force ("IETF").
+ Libreswan is a free software implementation of the most widely supported and
+ standardized VPN protocol based on ("IPsec") and the Internet Key Exchange
+ ("IKE"). These standards are produced and maintained by the Internet
+ Engineering Task Force ("IETF").
endef
define Package/libreswan/conffiles
/etc/ipsec.d
-/etc/ipsec.conf
-/etc/ipsec.secrets
+/etc/config/libreswan
+/etc/ipsec.user
endef
+
TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
MAKE_FLAGS+= \
define Package/libreswan/install
$(INSTALL_DIR) \
- $(1)/etc/init.d \
$(1)/etc/ipsec.d/policies \
$(1)/usr/libexec/ipsec \
- $(1)/usr/sbin
+ $(1)/usr/sbin \
+ $(1)/etc/config \
+ $(1)/etc/init.d \
+ $(1)/etc/hotplug.d/libreswan \
+ $(1)/etc/hotplug.d/iface \
+ $(1)/usr/libexec/rpcd \
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ipsec \
$(1)/usr/sbin/ipsec
- $(INSTALL_BIN) ./files/ipsec.init $(1)/etc/init.d/ipsec
- $(INSTALL_DATA) ./files/ipsec.conf $(1)/etc/ipsec.conf
- $(INSTALL_DATA) ./files/ipsec.secrets $(1)/etc/ipsec.secrets
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/ipsec.d/policies/* \
$(1)/etc/ipsec.d/policies/
$(CP) $(PKG_INSTALL_DIR)/usr/libexec/ipsec/* \
$(1)/usr/libexec/ipsec/
+
+ $(INSTALL_BIN) ./files/usr/libexec/ipsec/_updown.xfrm $(1)/usr/libexec/ipsec/_updown.xfrm
+ $(INSTALL_BIN) ./files/etc/init.d/ipsec $(1)/etc/init.d/ipsec
+ $(INSTALL_BIN) ./files/usr/libexec/rpcd/libreswan $(1)/usr/libexec/rpcd/libreswan
+ $(INSTALL_DATA) ./files/etc/ipsec.conf $(1)/etc/ipsec.conf
+ $(INSTALL_DATA) ./files/etc/ipsec.secrets $(1)/etc/ipsec.secrets
+ $(INSTALL_DATA) ./files/etc/config/libreswan $(1)/etc/config/libreswan
+ $(INSTALL_DATA) ./files/etc/hotplug.d/libreswan/01-user $(1)/etc/hotplug.d/libreswan/01-user
+ $(INSTALL_DATA) ./files/etc/hotplug.d/libreswan/02-vti $(1)/etc/hotplug.d/libreswan/02-vti
+ $(INSTALL_DATA) ./files/etc/hotplug.d/iface/89-libreswan $(1)/etc/hotplug.d/iface/89-libreswan
+endef
+
+define Package/libreswan-nftables
+ $(Package/libreswan/default)
+ TITLE+= nftables plugin)
+ DEPENDS+=firewall4 +libreswan +kmod-nft-xfrm +nftables \
+ +kmod-nfnetlink-log
+endef
+
+define Package/libreswan-nftables/description
+ Provides Libreswan nftables plugin for adding firewall rules
+endef
+
+define Package/libreswan-nftables/install
+ $(INSTALL_DIR) $(1)/etc/hotplug.d/libreswan \
+ $(1)/usr/share/nftables.d/ruleset-post
+
+ $(CP) ./files/usr/share/nftables.d/* $(1)/usr/share/nftables.d
+ $(CP) ./files/etc/hotplug.d/libreswan/62-nftables $(1)/etc/hotplug.d/libreswan/62-nftables
+ $(LN) /tmp/libreswan/firewall.d/libreswan.rules $(1)/usr/share/nftables.d/ruleset-post/10_libreswan.nft
+endef
+
+define Package/libreswan-iptables
+ $(Package/libreswan/default)
+ TITLE+= iptables plugin)
+ DEPENDS+=firewall +libreswan +iptables-mod-ipsec +kmod-ipt-ipsec \
+ +iptables-zz-legacy +IPV6:ip6tables-zz-legacy \
+ +kmod-ipt-nflog +iptables-mod-nflog
+endef
+
+define Package/libreswan-iptables/description
+ Provides Libreswan iptables plugin for adding firewall rules
+endef
+
+define Package/libreswan-iptables/install
+ $(INSTALL_DIR) $(1)/etc \
+ $(1)/etc/uci-defaults \
+ $(1)/etc/hotplug.d/libreswan
+
+ $(CP) ./files/etc/hotplug.d/libreswan/61-iptables $(1)/etc/hotplug.d/libreswan/61-iptables
+ $(CP) ./files/etc/uci-defaults/091-libreswan $(1)/etc/uci-defaults/091-libreswan
+ $(INSTALL_BIN) ./files/etc/libreswan_firewall.sh $(1)/etc/libreswan_firewall.sh
+endef
+
+define Package/libreswan-iptables/postinst
+#!/bin/sh
+[ -n "$$IPKG_INSTROOT" ] || {
+ /etc/init.d/firewall reload
+}
endef
$(eval $(call BuildPackage,libreswan))
+$(eval $(call BuildPackage,libreswan-nftables))
+$(eval $(call BuildPackage,libreswan-iptables))
--- /dev/null
+config libreswan 'globals'
+ option debug '0' # set debug mode none/all
+ list virtual_private '10.0.0.0/8'
+ list virtual_private '192.168.0.0/16'
+ list virtual_private '172.16.0.0/12'
+ list virtual_private '25.0.0.0/8'
+ list virtual_private '100.64.0.0/10'
+ list virtual_private '!100.64.0.0/24' # the address ranges that may live behind a NAT router through which a client connects
+ # option listen '192.168.2.100' # listening address, if set listen_interface would not be used
+ # option listen_interface 'wan' # listening interface
+ # option uniqueids 'yes' # yes/no
+
+# config crypto_proposal 'p1'
+# list encryption_algorithm '3des' # possible values: 3des, aes, aes_ctr, aes_cbc, aes128, aes192, aes256, camellia_cbc
+# list hash_algorithm 'md5' # possible values: md5, sha1, sha256, sha384, sha512
+# list dh_group 'modp1536' # possible values: modp1536, modp2048, modp3072, modp4096, modp6144, modp8192, dh19, dh20, dh21, dh22, dh31
+
+# config tunnel 'vti2_1_5'
+# option left '192.168.1.1'
+# option left_interface 'wan' # interface ipaddr to be used as left
+# option leftid '@left' # local id
+# option right '192.168.2.201' # remote endpoint public ip
+# option rightid '@62dd3e3f82339b002405245b' # rightid
+# option auto 'start' # what operation, should be done automatically at IPsec startup
+# option authby 'secret' # how the two security gateways should authenticate each other
+# option psk 'AyG9RlTtQJIUxgxG' # preshare key
+# option ikev2 '1' # ike version
+# option ikelifetime '8h'
+# option rekey '1'
+# option rekeymargin '9m'
+# option dpdaction 'restart'
+# option dpddelay '30'
+# option dpdtimeout '150'
+# option interface 'vti2_1_5' # only for route based tunnels
+# list leftsubnets '0.0.0.0/0'
+# list rightsubnets '0.0.0.0/0'
+# option phase2 'esp' # phase2 protocol
+# list ike 'p1' # list of crypto_proposal (phase1 proposals)
+# list phase2ag 'p1' # list of crypto_proposal (phase2 proposals')
+# option nflog '0' # enable nflog
+# option update_peeraddr '1' # auto update vti interface ppeeradd in /etc/config/network
--- /dev/null
+#!/bin/sh
+
+[ "$ACTION" = ifup -o "$ACTION" = ifupdate ] || exit 0
+[ "$ACTION" = ifupdate -a -z "$IFUPDATE_ADDRESSES" -a -z "$IFUPDATE_DATA" ] && exit 0
+
+/etc/init.d/ipsec running || exit 0
+uci show libreswan | grep -i "='$INTERFACE'$" || exit 0
+
+logger -t libreswan "Restart libreswan due to $ACTION of $INTERFACE ($DEVICE)"
+
+/etc/init.d/ipsec restart
--- /dev/null
+#!/bin/sh
+
+# Things that this script gets (from ipsec_pluto(8) man page)
+#
+# PLUTO_VERB
+# specifies the name of the operation to be performed
+# (prepare-host, prepare-client, up-host, up-client,
+# down-host, or down-client). If the address family
+# for security gateway to security gateway
+# communications is IPv6, then a suffix of -v6 is added
+# to the verb.
+#
+# PLUTO_CONNECTION
+# is the name of the connection for which we are
+# routing.
+#
+# PLUTO_CONNECTION_TYPE
+# is type of the connection, "tunnel" or "transport".
+#
+# PLUTO_CONN_POLICY
+# the policy of the connection, as in:
+# RSASIG+ENCRYPT+TUNNEL+PFS+DONTREKEY+OPPORTUNISTIC
+# +failureDROP+lKOD+rKOD
+#
+# CAT=YES|
+# if client address translation inside IPsec stack is enabled
+#
+# PLUTO_NEXT_HOP
+# is the next hop to which packets bound for the peer
+# must be sent.
+#
+# PLUTO_INTERFACE
+# is the name of the real interface used by encrypted traffic and IKE traffic
+#
+# PLUTO_ME
+# is the IP address of our host.
+#
+# PLUTO_MY_ID
+# is our ID.
+#
+# PLUTO_METRIC
+# is the metric to set for the route
+#
+# PLUTO_MTU
+# is the mtu to set for the route
+#
+# PLUTO_ADD_TIME
+# Time the IPsec SA was added to the kernel
+#
+# PLUTO_MOBIKE_EVENT
+# wether the connection is underdoing MOBIKE migration
+#
+# PLUTO_MY_CLIENT
+# is the IP address / count of our client subnet. If
+# the client is just the host, this will be the
+# host's own IP address / mask (where max is 32 for
+# IPv4 and 128 for IPv6).
+#
+# PLUTO_MY_CLIENT_NET
+# is the IP address of our client net. If the client
+# is just the host, this will be the host's own IP
+# address.
+#
+# PLUTO_MY_CLIENT_MASK
+# is the mask for our client net. If the client is
+# just the host, this will be 255.255.255.255.
+#
+# PLUTO_MY_SOURCEIP
+# if non-empty, then the source address for the route will be
+# set to this IP address.
+#
+# PLUTO_MY_PROTOCOL
+# is the protocol for this connection. Useful for
+# firewalling.
+#
+# PLUTO_MY_PORT
+# is the port. Useful for firewalling.
+#
+# PLUTO_PEER
+# is the IP address of our peer.
+#
+# PLUTO_PEER_ID
+# is the ID of our peer.
+#
+# PLUTO_PEER_CLIENT
+# is the IP address / count of the peer's client subnet.
+# If the client is just the peer, this will be
+# the peer's own IP address / mask (where max is 32
+# for IPv4 and 128 for IPv6).
+#
+# PLUTO_PEER_CLIENT_NET
+# is the IP address of the peer's client net. If the
+# client is just the peer, this will be the peer's
+# own IP address.
+#
+# PLUTO_PEER_CLIENT_MASK
+# is the mask for the peer's client net. If the
+# client is just the peer, this will be
+# 255.255.255.255.
+#
+# PLUTO_PEER_PROTOCOL
+# is the protocol set for remote end with port
+# selector.
+#
+# PLUTO_PEER_PORT
+# is the peer's port. Useful for firewalling.
+#
+# PLUTO_PEER_CA
+# is the DN of the peer's CA that signed its certificate
+#
+# PLUTO_CFG_CLIENT=0|1
+# is MODECFG or IKEv2 Config client.
+#
+# PLUTO_CFG_SERVER=0|1
+# is MODECFG or IKEv2 Config server.
+#
+# PLUTO_PEER_DNS_INFO
+# The peer's supplied DNS information (IKEv1 and IKEv2)
+#
+# PLUTO_PEER_DOMAIN_INFO
+# The peer's supplied domain list for local resolving (IKEv2 only)
+#
+# PLUTO_PEER_BANNER
+# is the peer's provided banner
+#
+# PLUTO_NM_CONFIGURED=0|1
+# is NetworkManager used for resolv.conf update
+#
+# PLUTO_CONN_ADDRFAMILY
+# is the family type, "ipv4" or "ipv6"
+#
+# PLUTO_CONN_KIND
+# is the "kind" of connection (CK_PERMANENT, CK_INSTANCE, etc)
+#
+# PLUTO_STACK
+# is the local IPsec kernel stack used, eg XFRM, BSDKAME, NOSTACK
+#
+# PLUTO_IS_PEER_CISCO=0|1
+# remote server type is cisco. Add support for cisco extensions
+# when used with xauth.
+#
+# PLUTO_SA_REQID
+# When using KAME or XFRM, the IPsec SA reqid base value.
+# ESP/AH out is base, ESP/AH in = base + 1
+# IPCOMP is base + 2 plus for inbound + 1
+#
+# PLUTO_XFRMI_FWMARK
+# use outgoing mark
+#
+# PLUTO_SA_TYPE
+# The type of IPsec SA (ESP or AH)
+#
+# PLUTO_USERNAME
+# The username (XAUTH or GSSAPI) that was authenticated (if any)
+# for this SA
+#
+# PLUTO_VIRT_INTERFACE
+# is the name of ipsec interface used by clear traffic in/out
+#
+# INTERFACE_IP
+# The IP to configure / expect on the interface? Currently is never set
+#
+# PLUTO_XFRM_ROUTE
+# if an XFRM (ipsec-device) has been specified, value will be "yes"
+#
+# XAUTH_FAILED
+# If xauthfail=soft this will be set to 1 if XAUTH authentication
+# failed. If xauthfail=hard, the updown scripts never run.
+#
+# CONNMARK
+# If mark= is set on the connection, this variable will be
+# set with the value. It can be used for iptables or VTI.
+#
+# CONNMARK_IN
+# the incoming mark to use
+#
+# CONNMARK_OUT
+# the outgoing mark to use
+#
+# VTI_IFACE=iface
+# Name of VTI interface to create
+#
+# VTI_ROUTING=yes|no
+# Whether or not to perform ip rule and ip route commands
+# covering the IPsec SA address ranges to route those packets
+# into the VTI_IFACE interface. This should be enabled unless
+# the IPsec SA covers 0.0.0.0/0 <-> 0.0.0.0/0
+#
+# VTI_SHARED=yes|no
+# Whether or not more conns (or instances) share a VTI device.
+# If not shared, the VTI device is deleted when tunnel goes down.
+#
+# VTI_IP
+# The IP to configure on the VTI device
+#
+# SPI_IN / SPI_OUT
+# The inbound and outbound SPI's of the connection.
+#
+# PLUTO_INBYTES
+# total bytes received
+#
+# PLUTO_OUTBYTES
+# total bytes sent
+#
+# NFLOG
+# is the nflog group to use
+#
+
+case "${PLUTO_VERB}" in
+ prepare-host|prepare-host-v6) ;;
+ prepare-client|prepare-client-v6) ;;
+ route-host|route-host-v6) ;;
+ unroute-host|unroute-host-v6) ;;
+ route-client|route-client-v6) ;;
+ unroute-client|unroute-client-v6) ;;
+ up-host|up-host-v6) ;;
+ down-host|down-host-v6) ;;
+ up-client|up-client-v6) ;;
+ down-client|down-client-v6) ;;
+esac
--- /dev/null
+#!/bin/sh
+
+[ -e "/etc/ipsec.user" ] && {
+ . /etc/ipsec.user
+}
+
+exit 0
--- /dev/null
+#!/bin/sh
+
+. /lib/functions.sh
+
+[ "${PLUTO_VERB}" != "route-client" ] && [ "${PLUTO_VERB}" != "up-client" ] && exit 0
+
+CONNECTION=${PLUTO_CONNECTION%/*}
+[ -z "$CONNECTION" ] && exit 0
+
+update_peeraddr=$(uci_get libreswan $CONNECTION update_peeraddr)
+[ "$update_peeraddr" != "1" ] && exit 0
+
+interface=$(uci_get libreswan $CONNECTION interface)
+[ -z "$interface" ] && exit 0
+
+proto=$(uci_get network "$interface" proto)
+[ "$proto" != "vti" ] && exit 0
+
+peeraddr=$(uci_get network "$interface" peeraddr)
+[ "$peeraddr" == "$PLUTO_PEER" ] && exit 0
+
+uci_set network "$interface" peeraddr "$PLUTO_PEER"
+uci_commit network
+ifup "$interface"
--- /dev/null
+#!/bin/sh
+
+. /lib/functions.sh
+
+FW4="$(command -v fw4)"
+[ -n "$FW4" ] && exit 0
+
+CONNECTION="${PLUTO_CONNECTION//\//_}"
+[ -z "$CONNECTION" ] && exit 0
+
+IPT_LEGACY="$(command -v iptables-legacy)"
+IPT="$(command -v iptables)"
+BIN="${IPT_LEGACY:-$IPT}"
+[ -z "$BIN" ] && exit 0
+
+LIBRESWAN_INPUT="libreswan_input"
+LIBRESWAN_FORWARD="libreswan_forward"
+LIBRESWAN_OUTPUT="libreswan_output"
+LIBRESWAN_NFLOG_INPUT="libreswan_nflog_input"
+LIBRESWAN_NFLOG_OUTPUT="libreswan_nflog_output"
+LIBRESWAN_POSTROUTING="libreswan_postrouting"
+
+FW_DIR="/tmp/libreswan/firewall.d"
+LIBRESWAN_RULES_FILE="$FW_DIR/libreswan.rules"
+RULES_DIR="$FW_DIR/rules"
+
+IPV4_RULES_FILE="$RULES_DIR/${CONNECTION}-ipv4.rules"
+IPV6_RULES_FILE="$RULES_DIR/${CONNECTION}-ipv6.rules"
+
+reload_firewall() {
+ [ ! -d "$RULES_DIR" ] && return 0
+
+ cat $RULES_DIR/*.rules > "$LIBRESWAN_RULES_FILE" 2>/dev/null
+ /etc/init.d/firewall reload
+}
+
+up_rules() {
+ [ -z "$PLUTO_PEER_CLIENT" ] && return 0
+
+ [ ! -d "$RULES_DIR" ] && mkdir -p "$RULES_DIR"
+ [ "$PLUTO_PEER_CLIENT" = "0.0.0.0/0" ] && [ "$PLUTO_MY_CLIENT" = "0.0.0.0/0" ] && return 0
+
+ cat << EOF > $IPV4_RULES_FILE
+$BIN -t filter -A $LIBRESWAN_INPUT -m policy --dir in --pol ipsec -s $PLUTO_PEER_CLIENT -d $PLUTO_MY_CLIENT -m comment --comment "$PLUTO_CONNECTION" -j ACCEPT
+$BIN -t filter -A $LIBRESWAN_FORWARD -s $PLUTO_PEER_CLIENT -d $PLUTO_MY_CLIENT -m comment --comment "$PLUTO_CONNECTION" -j ACCEPT
+$BIN -t filter -A $LIBRESWAN_OUTPUT -m policy --dir out --pol ipsec -s $PLUTO_MY_CLIENT -d $PLUTO_PEER_CLIENT -m comment --comment "$PLUTO_CONNECTION" -j ACCEPT
+$BIN -t nat -A $LIBRESWAN_POSTROUTING -m policy --dir out --pol ipsec -s $PLUTO_MY_CLIENT -d $PLUTO_PEER_CLIENT -m comment --comment "$PLUTO_CONNECTION" -j ACCEPT
+EOF
+ if [ -n "$NFLOG" ]; then
+ cat << EOF > $IPV4_RULES_FILE
+$BIN -t filter -A $LIBRESWAN_NFLOG_INPUT -m policy --dir in --pol ipsec -s $PLUTO_PEER_CLIENT -d $PLUTO_MY_CLIENT -j NFLOG --nflog-group $NFLOG --nflog-prefix $PLUTO_CONNECTION
+$BIN -t filter -A $LIBRESWAN_NFLOG_OUTPUT -m policy --dir out --pol ipsec -s $PLUTO_MY_CLIENT -d $PLUTO_PEER_CLIENT -j NFLOG --nflog-group $NFLOG --nflog-prefix $PLUTO_CONNECTION
+EOF
+
+ fi
+
+ reload_firewall
+
+ return 0
+}
+
+down_rules() {
+ if [ -f "$IPV4_RULES_FILE" ]; then
+ rm -rf "$IPV4_RULES_FILE"
+ reload_firewall
+ fi
+
+ return 0
+}
+
+case "${PLUTO_VERB}" in
+ up-host|up-client) up_rules ;;
+ down-host|down-client) down_rules ;;
+ up-host-v6|down-host-v6) ;;
+ up-client|down-client-v6) ;;
+esac
--- /dev/null
+#!/bin/sh
+
+. /lib/functions.sh
+
+FW4="$(command -v fw4)"
+[ -z "$FW4" ] && exit 0
+
+CONNECTION="${PLUTO_CONNECTION//\//_}"
+[ -z "$CONNECTION" ] && exit 0
+
+FW_DIR="/tmp/libreswan/firewall.d"
+LIBRESWAN_RULES_FILE="$FW_DIR/libreswan.rules"
+RULES_DIR="$FW_DIR/rules"
+
+IPV4_RULES_FILE="$RULES_DIR/${CONNECTION}-ipv4.rules"
+IPV6_RULES_FILE="$RULES_DIR/${CONNECTION}-ipv6.rules"
+NFLOG_ALL_RULES_FILE="$RULES_DIR/nflog_all.rules"
+
+reload_firewall() {
+ [ ! -d "$RULES_DIR" ] && return 0
+
+ cat $RULES_DIR/*.rules > "$LIBRESWAN_RULES_FILE" 2>/dev/null
+ /etc/init.d/firewall reload
+}
+
+up_rules() {
+ [ -z "$PLUTO_PEER_CLIENT" ] && return 0
+
+ [ ! -d "$RULES_DIR" ] && mkdir -p "$RULES_DIR"
+
+ eval $(ipsec addconn --configsetup)
+
+ if [ -n "$nflog_all" ]; then
+ unset NFLOG
+ if [ ! -f "$NFLOG_ALL_RULES_FILE" ]; then
+ cat << EOF > "$NFLOG_ALL_RULES_FILE"
+table inet fw4 {
+ chain libreswan_nflog_input {
+ meta ipsec exists log prefix "all-ipsec" group ${nflog_all}
+ }
+ chain libreswan_nflog_output {
+ rt ipsec exists log prefix "all-ipsec" group ${nflog_all}
+ }
+}
+EOF
+ fi
+ else
+ [ -f "$NFLOG_ALL_RULES_FILE" ] && rm -f "$NFLOG_ALL_RULES_FILE"
+ fi
+
+ cat << EOF > $IPV4_RULES_FILE
+table inet fw4 {
+ chain libreswan_input {
+ meta ipsec exists ipsec in ip saddr $PLUTO_PEER_CLIENT ip daddr $PLUTO_MY_CLIENT ${NFLOG:+log prefix \"${PLUTO_CONNECTION}\" group ${NFLOG}} accept comment "$PLUTO_CONNECTION"
+ }
+ chain libreswan_forward {
+ meta ipsec exists ipsec in ip saddr $PLUTO_PEER_CLIENT ip daddr $PLUTO_MY_CLIENT accept comment "$PLUTO_CONNECTION"
+ }
+ chain libreswan_output {
+ ipsec out ip saddr $PLUTO_MY_CLIENT ip daddr $PLUTO_PEER_CLIENT ${NFLOG:+log prefix \"${PLUTO_CONNECTION}\" group ${NFLOG}} accept comment "$PLUTO_CONNECTION"
+ }
+ chain libreswan_srcnat {
+ ip saddr $PLUTO_MY_CLIENT ip daddr $PLUTO_PEER_CLIENT accept comment "$PLUTO_CONNECTION"
+ }
+}
+EOF
+
+ reload_firewall
+
+ return 0
+}
+
+down_rules() {
+ if [ -f "$IPV4_RULES_FILE" ]; then
+ rm -rf "$IPV4_RULES_FILE"
+ reload_firewall
+ fi
+
+ return 0
+}
+
+case "${PLUTO_VERB}" in
+ up-host|up-client) up_rules ;;
+ down-host|down-client) down_rules ;;
+ up-host-v6|down-host-v6) ;;
+ up-client|down-client-v6) ;;
+esac
--- /dev/null
+#!/bin/sh /etc/rc.common
+
+. "${IPKG_INSTROOT}/lib/functions/network.sh"
+
+START=90
+STOP=10
+
+USE_PROCD=1
+
+PROG="/usr/libexec/ipsec/pluto"
+IPSEC_BIN="/usr/sbin/ipsec"
+
+IPSEC_DIR="/var/run/ipsec"
+IPSEC_CONF="$IPSEC_DIR/setup.conf"
+IPSEC_CONF_DIR="$IPSEC_DIR/conf.d"
+
+IPSEC_AUTO="${IPSEC_BIN} auto"
+
+extra_command "start_tunnel" "Start ipsec tunnel"
+extra_command "stop_tunnel" "Stop ipsec tunnel"
+extra_command "reload_tunnel" "Reload/restart ipsec tunnel"
+
+set_var() {
+ export "$1=$2"
+}
+
+get_var() {
+ local var
+
+ var=$(eval echo "\"\${${1}}\"")
+ [ "$var" = "1" ] && return 0
+
+ return 1
+}
+
+set_restart_flag() {
+ set_var "RESTART_IPSEC" 1
+}
+
+restart_flag() {
+ get_var RESTART_IPSEC
+}
+
+set_replace_flag() {
+ set_var "REPLACE_${1}" 1
+}
+
+replace_flag() {
+ get_var "REPLACE_${1}"
+}
+
+checkconfig() {
+ ${IPSEC_BIN} addconn --checkconfig || return 1
+ mkdir -p /var/run/pluto
+}
+
+expand_ike() {
+ local id="$1"
+ local encryption_algorithm hash_algorithm dh_group proposal
+
+ config_get encryption_algorithm "${id}" encryption_algorithm
+ config_get hash_algorithm "${id}" hash_algorithm
+ config_get dh_group "${id}" dh_group
+
+ encryption_algorithm="${encryption_algorithm% *}"
+ proposal="${encryption_algorithm:+${encryption_algorithm}${hash_algorithm:+-${hash_algorithm}${dh_group:+;${dh_group%% *}}}}"
+ append ike_proposal "$proposal" ","
+}
+
+expand_phase2alg() {
+ local id="$1"
+ local encryption_algorithm hash_algorithm dh_group
+
+ config_get encryption_algorithm "${id}" encryption_algorithm
+ config_get hash_algorithm "${id}" hash_algorithm
+ config_get dh_group "${id}" dh_group
+
+ phase2alg_proposal="${encryption_algorithm:+${encryption_algorithm// /+}${hash_algorithm:+-${hash_algorithm// /+}${dh_group:+-${dh_group// /+}}}}"
+}
+
+generate_tunnel_config() {
+ local id=$1
+ local config_file="$IPSEC_CONF_DIR/$id.conf"
+ local secret_file="$IPSEC_CONF_DIR/$id.secret"
+ local tmp_config_file="/tmp/$id.conf"
+ local tmp_secret_file="/tmp/$id.secret"
+ local ikey mark_in okey mark_out ifid
+
+ config_get auto "$id" auto
+ config_get left "$id" left
+ config_get left_interface "$id" left_interface
+ [ -n "$left_interface" ] && network_get_ipaddr left "$left_interface"
+ config_get right "$id" right
+ config_get leftid "$id" leftid "$left"
+ config_get rightid "$id" rightid "$right"
+ config_get leftsourceip "$id" leftsourceip
+ config_get rightsourceip "$id" rightsourceip
+ config_get leftsubnets "$id" leftsubnets
+ config_get rightsubnets "$id" rightsubnets
+ config_get_bool ikev2 "$id" ikev2
+ [ "$ikev2" = "1" ] && ikev2=yes || ikev2=no
+ config_get_bool rekey "$id" rekey
+ [ "$rekey" = "1" ] && rekey=yes || rekey=no
+ config_get ikelifetime "$id" ikelifetime
+ config_get rekeymargin "$id" rekeymargin
+ config_get dpdaction "$id" dpdaction
+ config_get dpdtimeout "$id" dpdtimeout
+ config_get dpddelay "$id" dpddelay
+ config_get phase2 "$id" phase2
+ config_get phase2alg "$id" phase2alg
+ config_get nflog "$id" nflog 0
+ [ "$nflog" = "0" ] && unset nflog
+
+ config_list_foreach "$id" ike expand_ike
+ config_list_foreach "$id" phase2alg expand_phase2alg
+
+ config_get authby "$id" authby
+ config_get psk "$id" psk
+
+ if [ -n "$leftsubnets" ]; then
+ [[ "$leftsubnets" =~ 0.0.0.0* ]] && leftsubnets="0.0.0.0/0"
+ leftsubnets="{${leftsubnets// /,}}"
+ fi
+
+ if [ -n "$rightsubnets" ]; then
+ [[ "$rightsubnets" =~ 0.0.0.0* ]] && rightsubnets="0.0.0.0/0"
+ rightsubnets="{${rightsubnets// /,}}"
+ fi
+
+ config_get interface "$id" interface
+
+ cat << EOF > "$tmp_secret_file"
+$leftid $rightid : PSK "$psk"
+EOF
+
+ cat << EOF > "$tmp_config_file"
+conn $id
+ auto=${auto}
+ authby=${authby}
+ ikev2=${ikev2}
+ left=${left%% *}
+ ${leftid:+leftid=${leftid}}
+ ${leftsourceip:+leftsourceip=${leftsourceip}}
+ ${leftsubnets:+leftsubnets=${leftsubnets}}
+ right=${right%% *}
+ ${rightid:+rightid=${rightid}}
+ ${rightsourceip:+rightsourceip=${rightsourceip}}
+ ${rightsubnets:+rightsubnets=${rightsubnets}}
+ ${dpdaction:+dpdaction=${dpdaction}}
+ ${dpdtimeout:+dpdtimeout=${dpdtimeout}}
+ ${dpddelay:+dpddelay=${dpddelay}}
+ ${ikelifetime:+ikelifetime=${ikelifetime}}
+ ${rekey:+rekey=${rekey}}
+ ${rekeymargin:+rekeymargin=${rekeymargin}}
+ ${rekeyfuzz:+rekeyfuzz=${rekeyfuzz}}
+ ${phase2:+phase2=${phase2}}
+ ${ike_proposal:+ike=${ike_proposal}}
+ ${phase2alg_proposal:+phase2alg=${phase2alg_proposal}}
+ ${nflog:+nflog=${nflog}}
+EOF
+
+ if [ -n "$interface" ]; then
+ proto=$(uci_get network "$interface" proto)
+ case "$proto" in
+ vti)
+ ikey=$(uci_get network "$interface" ikey)
+ okey=$(uci_get network "$interface" okey)
+ mark_in=$(printf "0x%x" $ikey)
+ mark_out=$(printf "0x%x" $okey)
+ echo -e "${mark_in:+\tmark-in=${mark_in}}" >> "$tmp_config_file"
+ echo -e "${mark_out:+\tmark-out=${mark_out}}" >> "$tmp_config_file"
+ echo -e "${interface:+\tvti-interface=${interface}}" >> "$tmp_config_file"
+ ;;
+ xfrm)
+ ifid=$(uci_get network "$interface" ifid)
+ echo -e "${ifid:+\tipsec-interface=${ifid}}" >> "$tmp_config_file"
+ ;;
+ esac
+ fi
+
+
+ [ -f "$config_file" ] && {
+ cmp "$config_file" "$tmp_config_file" 2>/dev/null && rm -f "$tmp_config_file"
+ }
+
+ [ -f "$secret_file" ] && {
+ cmp "$secret_file" "$tmp_secret_file" 2>/dev/null && rm -f "$tmp_secret_file"
+ }
+
+ [ -f "$tmp_config_file" ] && mv "$tmp_config_file" "$config_file" && set_replace_flag "$id"
+ [ -f "$tmp_secret_file" ] && mv "$tmp_secret_file" "$secret_file" && set_replace_flag "$id"
+
+ unset ike_proposal phase2alg_proposal
+}
+
+generate_daemon_config() {
+ local tmp_config_file="/tmp/setup.conf"
+
+ config_get_bool debug globals debug 0
+ [ "$debug" = "0" ] && debug=none || debug=all
+ config_get_bool uniqueids globals uniqueids 0
+ [ "$uniqueids" = "0" ] && uniqueids=no || uniqueids=yes
+ config_get listen globals listen
+ config_get listen_interface globals listen_interface
+ [ -n "$listen_interface" ] && network_get_ipaddr listen "$listen_interface"
+ config_get virtual_private globals virtual_private
+ [ -z "$virtual_private" ] && virtual_private='10.0.0.0/8 192.168.0.0/16 172.16.0.0/12 25.0.0.0/8 100.64.0.0/10 !100.64.0.0/24'
+ config_get nflog_all globals nflog_all 0
+ [ "$nflog_all" = "0" ] && unset nflog_all
+
+ [ ! -d $IPSEC_DIR ] && mkdir -p $IPSEC_DIR
+ [ ! -d $IPSEC_CONF_DIR ] && mkdir -p $IPSEC_CONF_DIR
+
+ cat << EOF > "$tmp_config_file"
+config setup
+ ${debug:+plutodebug=${debug}}
+ ${uniqueids:+uniqueids=${uniqueids}}
+ ${listen:+listen=${listen}}
+ ${virtual_private:+virtual-private=%v4:${virtual_private// /,%v4:}}
+ ${nflog_all:+nflog-all=${nflog_all}}
+EOF
+
+ if ! cmp "$IPSEC_CONF" "$tmp_config_file" 2>/dev/null; then
+ mv "$tmp_config_file" "$IPSEC_CONF"
+ set_restart_flag 1
+ else
+ rm -f "$tmp_config_file"
+ fi
+
+ return 0
+}
+
+clean_config() {
+ rm -f $IPSEC_CONF_DIR/*.conf $IPSEC_CONF_DIR/*.secret
+}
+
+config_cb() {
+ local var="CONFIG_${1}_SECTIONS"
+ export $var
+ append "$var" "$2"
+}
+
+generate_config() {
+ config_load libreswan
+ generate_daemon_config
+ config_foreach generate_tunnel_config tunnel
+}
+
+regenerate_config() {
+ clean_config
+ generate_config
+}
+
+active_conns() {
+ local active_conns file _file
+
+ active_conns=$(${IPSEC_BIN} --trafficstatus | awk -F'[":/]' '{print $3}' | sort -u)
+
+ for file in $IPSEC_CONF_DIR/*.conf; do
+ _file="${file##*/}"
+ list_contains active_conns "${_file%%.*}" || append active_conns "${_file%%.*}"
+ done
+
+ echo "$active_conns"
+}
+
+start_service() {
+ generate_config
+ checkconfig || return 1
+
+ ${IPSEC_BIN} _stackmanager start
+
+ procd_open_instance
+ procd_set_param command $PROG --nofork
+ procd_set_param respawn
+ procd_close_instance
+}
+
+stop_service() {
+ ${IPSEC_BIN} whack --shutdown
+ ${IPSEC_BIN} _stackmanager stop
+}
+
+stop_tunnel() {
+ ${IPSEC_AUTO} --delete "$1" > /dev/null 2>&1
+ rm -f ${IPSEC_CONF_DIR}/$1.*
+}
+
+start_tunnel() {
+ generate_tunnel_config "$1"
+ ${IPSEC_AUTO} --add "$1" > /dev/null 2>&1
+ ${IPSEC_AUTO} --rereadsecrets
+ ${IPSEC_AUTO} --up "$1" > /dev/null 2>&1 &
+}
+
+reload_tunnel() {
+ generate_tunnel_config "$1"
+
+ replace_flag "$1" || return 0
+
+ ${IPSEC_AUTO} --rereadsecrets
+ ${IPSEC_AUTO} --replace "$1" > /dev/null 2>&1
+ ${IPSEC_AUTO} --up "$1" > /dev/null 2>&1 &
+}
+
+reload_service() {
+ local active_tunnels uci_tunnels
+ uci_tunnels="$@"
+
+ config_load libreswan
+ generate_daemon_config
+
+ if restart_flag; then
+ restart
+ return 0
+ fi
+
+ [ -z "$uci_tunnels" ] && config_get uci_tunnels tunnel SECTIONS
+
+ active_tunnels="$(active_conns)"
+
+ for tunnel in $active_tunnels; do
+ list_contains uci_tunnels "$tunnel" || stop_tunnel "$tunnel"
+ done
+
+ for tunnel in $uci_tunnels; do
+ if list_contains active_tunnels "$tunnel"; then
+ reload_tunnel "$tunnel"
+ else
+ start_tunnel "$tunnel"
+ fi
+ done
+}
+
+service_triggers() {
+ procd_add_reload_trigger 'libreswan'
+}
--- /dev/null
+include /var/run/ipsec/setup.conf
+include /var/run/ipsec/conf.d/*.conf
+include /etc/ipsec.d/*.conf
--- /dev/null
+include /var/run/ipsec/conf.d/*.secret
+include /etc/ipsec.d/*.secrets
--- /dev/null
+#!/bin/sh
+
+FW4="$(command -v fw4)"
+[ -n "$FW4" ] && exit 0
+
+IPT_LEGACY="$(command -v iptables-legacy)"
+IPT="$(command -v iptables)"
+BIN="${IPT_LEGACY:-$IPT}"
+[ -z "$BIN" ] && exit 0
+
+LIBRESWAN_INPUT="libreswan_input"
+LIBRESWAN_FORWARD="libreswan_forward"
+LIBRESWAN_OUTPUT="libreswan_output"
+LIBRESWAN_NFLOG_INPUT="libreswan_nflog_input"
+LIBRESWAN_NFLOG_OUTPUT="libreswan_nflog_output"
+LIBRESWAN_POSTROUTING="libreswan_postrouting"
+
+FW_DIR="/tmp/libreswan/firewall.d"
+LIBRESWAN_RULES_FILE="$FW_DIR/libreswan.rules"
+
+flush_delete_chain() {
+ [ $# -lt 2 ] && return
+
+ $BIN -t $1 -nL $2 > /dev/null 2>&1 || return
+
+ $BIN -t $1 -F $2
+ $BIN -t $1 -X $2
+}
+
+cleanup_libreswan_rules() {
+ $BIN -t filter -C input_rule -j $LIBRESWAN_INPUT > /dev/null 2>&1
+ [ $? -eq 0 ] && $BIN -t filter -D input_rule -j $LIBRESWAN_INPUT
+
+ $BIN -t filter -C output_rule -j $LIBRESWAN_OUTPUT > /dev/null 2>&1
+ [ $? -eq 0 ] && $BIN -t filter -D output_rule -j $LIBRESWAN_OUTPUT
+
+ $BIN -t filter -C forwarding_rule -j $LIBRESWAN_FORWARD > /dev/null 2>&1
+ [ $? -eq 0 ] && $BIN -t filter -D forwarding_rule -j $LIBRESWAN_FORWARD
+
+ $BIN -t nat -C postrouting_rule -j $LIBRESWAN_POSTROUTING > /dev/null 2>&1
+ [ $? -eq 0 ] && $BIN -t nat -D postrouting_rule -j $LIBRESWAN_POSTROUTING
+
+ flush_delete_chain filter $LIBRESWAN_NFLOG_INPUT
+ flush_delete_chain filter $LIBRESWAN_INPUT
+ flush_delete_chain filter $LIBRESWAN_FORWARD
+ flush_delete_chain filter $LIBRESWAN_NFLOG_OUTPUT
+ flush_delete_chain filter $LIBRESWAN_OUTPUT
+ flush_delete_chain filter $LIBRESWAN_NFLOG_INPUT
+ flush_delete_chain filter $LIBRESWAN_NFLOG_OUTPUT
+ flush_delete_chain nat $LIBRESWAN_POSTROUTING
+}
+
+create_chain_jump() {
+ [ $# -lt 3 ] && return
+
+ local table=$1
+ local chain=$2
+ local base_chain=$3
+
+ $BIN -t $table -N $chain
+ $BIN -t $table -C $base_chain -j $chain
+ [ $? -ne 0 ] && $BIN -t $table -I $base_chain -j $chain
+ $BIN -t $table -F $chain
+}
+
+if ! /etc/init.d/ipsec running; then
+ cleanup_libreswan_rules
+ exit 0
+fi
+
+eval $(ipsec addconn --configsetup)
+
+create_chain_jump filter "$LIBRESWAN_INPUT" "insert_rule"
+create_chain_jump filter "$LIBRESWAN_FORWARD" "forwarding_rule"
+create_chain_jump filter "$LIBRESWAN_OUTPUT" "output_rule"
+
+create_chain_jump filter "$LIBRESWAN_NFLOG_INPUT" "$LIBRESWAN_INPUT"
+create_chain_jump filter "$LIBRESWAN_NFLOG_OUTPUT" "$LIBRESWAN_OUTPUT"
+
+create_chain_jump nat "$LIBRESWAN_POSTROUTING" "postrouting_rule"
+
+[ ! -f $LIBRESWAN_RULES_FILE ] && exit 0
+
+if [ -n "$nflog_all" ]; then
+ sed -i -e '/NFLOG/d' "$LIBRESWAN_RULES_FILE"
+ $BIN -t filter -I $LIBRESWAN_NFLOG_INPUT -m policy --dir in --pol ipsec -j NFLOG --nflog-group ${nflog_all} --nflog-prefix all-ipsec
+ $BIN -t filter -I $LIBRESWAN_NFLOG_OUTPUT -m policy --dir out --pol ipsec -j NFLOG --nflog-group ${nflog_all} --nflog-prefix all-ipsec
+fi
+
+sh $LIBRESWAN_RULES_FILE
--- /dev/null
+#!/bin/sh
+
+. /lib/functions.sh
+
+uci_add firewall include libreswan
+uci_set firewall libreswan path '/etc/libreswan_firewall.sh'
+uci_set firewall libreswan reload 1
+uci_commit firewall
+++ /dev/null
-config setup
- # needed when using PSK only. Not needed for X.509 based servers
- uniqueids=no
- virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v4:100.64.0.0/10,%v4:!100.64.0.0/24
-
-conn ikev1
- authby=secret
- pfs=no
- auto=add
- rekey=no
- left=%defaultroute
- right=%any
- ikev2=never
- type=transport
- leftprotoport=17/1701
- rightprotoport=17/%any
- dpddelay=15
- dpdtimeout=30
- dpdaction=clear
-
-conn ikev1-nat
- also=ikev1
- rightsubnet=vhost:%priv
-
-# include /etc/ipsec.d/*.conf
+++ /dev/null
-#!/bin/sh /etc/rc.common
-
-START=90
-STOP=10
-
-USE_PROCD=1
-PROG="/usr/libexec/ipsec/pluto"
-IPSEC_SECRETS=/etc/ipsec.secrets
-IPSEC_CONF=/etc/ipsec.conf
-IPSEC_BIN=/usr/sbin/ipsec
-
-checkconfig() {
- ${IPSEC_BIN} addconn --checkconfig || return 1
- mkdir -p /var/run/pluto
-}
-
-start_service() {
- checkconfig || return 1
-
- ipsec _stackmanager start
- # Enable nflog if configured
- ipsec --checknflog > /dev/null
-
- procd_open_instance
- procd_set_param command $PROG --config ${IPSEC_CONF} --nofork --secretsfile ${IPSEC_SECRETS}
- procd_set_param respawn
- procd_close_instance
-}
-
-stop_service() {
- ipsec whack --shutdown
- ipsec _stackmanager stop
- ipsec --stopnflog > /dev/null
-
-}
-
+++ /dev/null
-# Unlike older openswan, this file does NOT contain any X.509 related
-# information such as private key :RSA statements as these now reside
-# in the NSS database. See:
-#
-# https://libreswan.org/wiki/Using_NSS_with_libreswan
-# https://libreswan.org/wiki/Migrating_from_Openswan
-
-# A.B.C.D %any : PSK "SsEeCcRrEeTt"
-: PSK "SsEeCcRrEeTt"
-# include /etc/ipsec.d/*.secrets
--- /dev/null
+#!/bin/sh
+
+/sbin/hotplug-call libreswan
--- /dev/null
+#!/bin/sh
+
+. /lib/functions.sh
+. /usr/share/libubox/jshn.sh
+
+RPC_SCRIPTS=/usr/libexec/libreswan/rpc
+
+[ -d $RPC_SCRIPTS ] && include $RPC_SCRIPTS
+
+IPSEC_TRAFFIC_STATES="/tmp/ipsec_traffic.$$"
+IPSEC_TUNNEL_STATUS="/tmp/ipsec_status.$$"
+
+__function__() {
+ type "$1" > /dev/null 2>&1
+}
+
+foreach_extra() {
+ local file obj
+
+ [ ! -d $RPC_SCRIPTS ] && return
+
+ for file in $RPC_SCRIPTS/*; do
+ obj="${file##*/}"
+ $1 "${obj%%.*}"
+ done
+}
+
+get_index() {
+ [ $# -lt 2 ] && return 1
+
+ local var=$1
+ local str=$2
+ local ele
+ local i=1
+
+ eval "val=\"\${$var}\""
+
+ for ele in ${val}; do
+ if [[ "$ele" = "$str" ]]; then
+ echo "$i"
+ return 0
+ fi
+ i="$((i+1))"
+ done
+
+ return 1
+}
+
+phase1_established() {
+ grep -q "\"${1%/*}\/.*(IKE SA established)\|\"${1%/*}\/.*(established IKE SA)" "$IPSEC_TUNNEL_STATUS"
+}
+
+phase2_established() {
+ grep -q "\"$1\".*(IPsec SA established)\|\"$1\".*(established Child SA)" "$IPSEC_TUNNEL_STATUS"
+}
+
+add_tunnel_object() {
+ local id="$1"
+ local leftsubnets rightsubnets right ctime active_right
+ local phase1=0 phase2=0 add_time inBytes outBytes
+
+ config_get right "$id" right
+ config_get leftsubnets "$id" leftsubnets
+ config_get rightsubnets "$id" rightsubnets
+
+ if [ -z "$right" ] || [ "$right" = "%any" ] || [ "$right" == "0.0.0.0" ]; then
+ active_right=$(awk -F'[: ]' '{ if ( $4 ~ "'"$id/"'") {print $5; exit 0};}' "$IPSEC_TUNNEL_STATUS")
+ fi
+
+ for lsubnet in $leftsubnets; do
+ lidx=$(get_index leftsubnets $lsubnet)
+ for rsubnet in $rightsubnets; do
+ ridx=$(get_index rightsubnets $rsubnet)
+ tid="${id}/${lidx}x${ridx}"
+
+ eval $(awk -F, '{if ($1 ~ "'"$tid"'" ) {printf("%s %s %s", $3, $4, $5)};}' "$IPSEC_TRAFFIC_STATES")
+ json_add_object tunnels
+ json_add_string name "$id"
+ json_add_string right "$right${active_right:+ (${active_right})}"
+ json_add_string leftsubnet "$lsubnet"
+ json_add_string rightsubnet "$rsubnet"
+ json_add_int tx "$outBytes"
+ json_add_int rx "$inBytes"
+
+ phase1_established "$tid" && phase1=1
+ phase2_established "$tid" && phase2=1
+
+ json_add_boolean phase1 "$phase1"
+ json_add_boolean phase2 "$phase2"
+
+ if [ "$phase1" = "1" ] && [ "$phase2" = "1" ]; then
+ ctime="$(date +%s)"
+ json_add_boolean connected 1
+ json_add_int uptime "$((ctime - add_time))"
+ else
+ json_add_boolean connected 0
+ json_add_int uptime 0
+ fi
+
+ json_close_object
+ done
+ done
+}
+
+generate_libreswan_states() {
+ ipsec trafficstatus > "$IPSEC_TRAFFIC_STATES"
+ ipsec status > "$IPSEC_TUNNEL_STATUS"
+}
+
+clean_libreswan_states() {
+ return
+ rm -f "$IPSEC_TRAFFIC_STATES" "$IPSEC_TUNNEL_STATUS"
+}
+
+libreswan_status() {
+ config_load libreswan
+
+ generate_libreswan_states
+
+ json_init
+ json_add_array tunnels
+ config_foreach add_tunnel_object tunnel
+ json_close_array
+ json_dump
+
+ clean_libreswan_states
+}
+
+call_extra() {
+ if __function__ "$1"; then
+ $1
+ else
+ json_init
+ json_add_string error "invalid call $1"
+ json_dump
+ fi
+}
+
+call_method() {
+ case "$1" in
+ status)
+ libreswan_status
+ ;;
+ *)
+ call_extra $1
+ ;;
+ esac
+}
+
+list_extra() {
+ if __function__ "${1}_help"; then
+ ${1}_help
+ else
+ json_add_object "$1"
+ json_close_object
+ fi
+}
+
+list_methods() {
+ local file
+
+ json_init
+
+ json_add_object status
+ json_close_object
+
+ foreach_extra list_extra ${1}
+
+ json_dump
+}
+
+main () {
+ case "$1" in
+ list)
+ list_methods
+ ;;
+ call)
+ call_method $2
+ ;;
+ esac
+}
+
+main "$@"
--- /dev/null
+jump libreswan_forward
--- /dev/null
+jump libreswan_nflog_input
+jump libreswan_input
--- /dev/null
+jump libreswan_nflog_output
+jump libreswan_output
--- /dev/null
+jump libreswan_srcnat
--- /dev/null
+chain libreswan_input {}
+chain libreswan_nflog_input {}
+chain libreswan_forward {}
+chain libreswan_output {}
+chain libreswan_nflog_output {}
+chain libreswan_srcnat {}