Notice: Undefined offset: 1 in /usr/local/src/wordpress/wp-content/themes/montezuma/includes/parse_php.php on line 79

Universal Encrypted Data In Transit – RHEL

Most companies today use Virtual Private Networks for remote users to connect with the enterprise, but few companies encrypt network traffic internally.   So why would universal encryption be a good idea?   Because perimeter defenses have become so good that most security breaches these days have happened when the instigator is already inside the system, as with phishing, SQL injection, or buffer overflow incursions.   Once inside, and with privilege escalation or a vulnerable switch, they can then monitor all traffic.

But let’s back up for a minute and consider VPNs.   A VPN is a ‘tunnel’ within the datastream which carries its data, isolated from the rest of the datastream by encryption.   It is only a ‘virtual’ tunnel since all the data is there with the rest of the crowd, but it is logically isolated from other packets as it is not cleartext.   The headers for its packets describe where it’s coming from, where it’s going, which packet it is in its stream, and information on the encryption, but the payload of each packet is encrypted using the cipher, hash, handshakes which were agreed to by both ends at the beginning of the session.   IPSec is not traditional encapsulation, where a packet is wrapped in an encryption protocol, which may be wrapped in yet another protocol.   IPSec flows in transport mode as normal packets, only encrypted.

Most conventional network services use password-based authentication, where a user supplies a password to access a given network server.   However, the transmission of authentication information for many services is unencrypted, so for such a username:password system to be secure the network must be inaccessible to third parties, and all computers and users on the network must be trusted and trustworthy.   Impractical.

So any attacker who gains access to a cleartext network can use a simple packet analyzer or packet sniffer, to intercept usernames and passwords, compromising user accounts and possibly the integrity of the entire security infrastructure.   This is why encrypting data in transit is important.

VLANs are commonly used to differentiate between constellations of servers, ie Finance is on one VLAN while Sales is on another.   But a VLAN is defined simply by a number in the packet header  —  the data payload in VLAN packets is not encrypted.   So VLAN is not secure.   I say again:  VLAN is not secure.

There are two general types of VPN:  IPSec, and TLS/OpenSSL.   This describes the structure of data and encryption in each case.   Many companies today use IPSec because it is quite secure (if well-configured), and it can be implemented by using pre-built hardware appliances, or through Microsoft products, or by using Strongswan for Linux.  (or other minor implementations of IPSec)   OpenVPN is the choice of most individual haqxors because, frankly it’s easy.   IPSec is not.   Red Hat says, “IKE/IPsec is the only VPN technology recommended for use in Red Hat Enterprise Linux 7.   Do not use any other VPN technology without understanding the risks of doing so.

IPSec provides:

  • Encryption
  • Authentication of hosts
  • Replay protection
  • Traffic flow confidentiality
  • Transport mode, not Tunnel mode (encapsulated VPN)
  • Extensibility to WLANs
  • No need for WPA, as IPSec is better
  • IPV6 support, in fact IPV6 mandates IPSec
  • Carries TCP, UDP, ICMP traffic, etc which other VPNs do not
  • IPsec packets use the ESP protocol – Show as “ESP” in a sniffer, not TCP or UDP, etc
  • Both ends must be configured

IPSec does not:

  • Provide authorization or user authentication;  this is done by normal means
  • Offer simplicity in setup, but only needs set up once
  • Require support in applications, as TLS does
  • Allow packet sniffing – bypasses any external firewall and can not be monitored
  • Need to be handled and managed  —  it is just there, invisible

IPSec VPN appliances are costly, but they do take the thinking and most error out of installation, while Microsoft’s IPSec solutions are more involved but still on the easy side.   However any system such as these which makes most of the decisions in lieu of an expert will necessarily mean many compromises.  —  compromises in deployment flexibility, configurability, security, and backward compatibility.   In this article I’ll describe in detail how to set up universal IPSec VPN using Strongswan for Red Hat Enterprise Linux, with the best encryption available.

When two sides would like to communicate securely, they must have a secure way to establish the connexion, and for Perfect Forward Secrecy a key must be unique for each session.   The problem is how do you get that key from one side to the other, safely?   This is why we have the Internet Key Exchange protocol (“IKE2”), which is a technique that uses some approach for setting up a secure connexion so it can share an agreed symmetric key with both ends, securely.   This approach can be ‘Pre-Shared Keys’ (not recommended), X.509 certificates, EAP, RADIUS, et al.   Once IKE has done its job and both ends have proven they are who they say they are, the IPSec session can begin in earnest.

meshIPSec VPNs by their nature are point-to-point.  —  one system establishes a trusted connexion with another system and they maintain communications practically impervious to third parties.   However IPSec policies can describe a whole subnet at once, i.e. act as templates for automatic “point-to-point” every time two hosts communicate.   This is ideal for the newest network architectures such as flat self-organizing, self-healing ‘fabric’ networks.


CAUTION:  Science Content

~~   The Details — How It Works   ~~

IPSec can use two different protocols to encapsulate the data over a VPN tunnel:

ESP is far more secure as it provides data encryption.
AH just provides authentication thus it is not used as much as ESP anymore.

The goal of the Internet Key Exchange (IKE2) is for both sides to independently produce the same symmetrical key.   This key then encrypts and decrypts the regular IP packets used in the bulk transfer of data between VPN peers.   IKE builds the VPN tunnel by authenticating both sides and reaching an agreement on methods of encryption and integrity.   The outcome of an IKE2 negotiation is a ‘Security Association’ (SA).   The setup works as follows:

  • Each host uses its certificate’s private key to sign a piece of data that is part of the key exchange.
  • The signature can be checked with the corresponding public certificate, by the machine on the other end.
  • The identity claimed by each peer has to be confirmed by the certificate by the Subject Alt Name (san) extension.
  • As soon as both sides have verified the authenticity, the transmitted data is used to negotiate the shared key, from which keys for encryption and MAC algorithms are derived for this IKE2 Security Association.
  • A host only ever has its own private key.   Nobody else has that particular private key.  (except for maybe the CA if you so choose)   All members of the VPN must have all other members’ public certs.
  • Each side derives a symmetric key for the VPN encryption.   If the symmetric keys don’t match, somebody doesn’t belong there, but when they do they can communicate securely.
  • The SA is now passed to the kernel, which will en/decrypt traffic using the (independently) derived symmetric key.

Diffie-Hellman is that part of the IKE protocol used for exchanging the material from which the symmetrical keys are built.   The Diffie-Hellman algorithm builds an encryption key known as a “shared secret” from the private key of one party, and the public key of the other.   Since the IPsec symmetrical keys are derived from this DH key shared between the peers, at no point are symmetric keys actually exchanged.

  • Diffie-Hellman key exchange uses a group of standardized global unique prime numbers and generators to provide secure asymmetric key exchange.
  • Diffie-Hellman only does key generation and exchange, and does not do data encryption, digital signatures nor any authentication.
  • It’s best to use Diffie-Hellman group 24, which is a modular exponentiation group with a 2048-bit modulus and 256-bit prime order subgroup.   IOW Next Generation Encryption.
  • The config format for ESP is ENC-AUTH followed by an optional PFSgroup.   For instance, “3desmd5” or “aes256sha1;modp2048” or “aessha1,aesmd5“.
  • For RFC-5114 DH groups (the best), use the “dh” keyword, eg “aes256sha1;dh24
  • Because a new DH key is generated during each IKE phase I, no dependency exists between these keys and those produced in subsequent IKE Phase I negotiations.
  • Perfect Forward Secrecy mode is supported only between gateways, not between Security Gateways and
    remote access clients.   Enable PFS in IKE phase II only in situations where extreme security is required.

When a NAT device does it’s NAT translations, the embedded address of the source computer within the IP payload does not match the source address of the IKE packet as it is replaced by the address of the NAT device.   This means breaking the authenticity, which will cause the packet by the remote peer to be dropped.   So when the NAT device alters the packet, it’s integrity and authentication will fail.   Also, the payload and in particular the headers are encrypted when using IPSec ESP mode.

This is no longer a problem with IKE2 as it automatically handles NAT traversal.   During phase 1, if NAT traversal is used, one or both peer’s identify to each other that they are using NAT traversal, then the IKE negotiations switch to using UDP port 4500.   After this the data is sent and handled using IPSec over UDP.   Two ports and one protocol must be open in and out on the device that is doing NAT for your VPN.   These are UDP port 4500 (used for NAT traversal), UDP port 500 (used for
IKE) and IP protocol 50 (ESP).

In the case of a remote device trying to connect to the IPSec gateway, how does the remote initiator prove it is who it says it is, when its IP changes and is not resolvable to a domain name?  (Remember, both ends have to prove they are who they say they are)   The responder uses the trust chain to verify that the client certificate was signed by a trusted Certificate Authority certificate, and checks the signature in the AUTH payload which proves that the initiator is in possession of its correct private key.   The DN and SANs are also used as identification of the remote initiator, and you could
match them in different configs.

So let’s consider Strongswan.   No one will tell you most of the stuff in this article, and I’m not so sure most fully understand it anyway.   With IPSec VPNs there is no client/server context  (and you will roundly have your knob knocked off for even whispering or thinking client/server)  —  there is initiator / responder (aka ‘Left/Right’), because either end can initiate a VPN connexion.   There is no server per se.   And it matters in the configuration whether you’re connecting net to net, multi-level LAN, with EAP, RADIUS, mobile devices, and so on;   multitudes of configurations.   And there are several methods of authentication, although remember that “PSK” (‘Pre-Shared Keys’) is discredited as an auth method.   Today we’ll configure the members of a LAN using X.509 certificates for auth.   Actually, we’ll use IPSec PKI certs, which are X.509v3 with Extended Key:  Server Authentication.   The only secure and manageable alternative is EAP with certificates (EAP-TLS), which means delegating authentication to RADIUS, which should be running in any case.

~~   Setting Up the Certificate Authority   ~~

X.509 can be a nightmare, and it has defeated many a mighty tech guru, to wit:

… but I am going to make it easy for you, and that’s a promise.  yep

Since we’re using certs we’ll need a certificate authority (“CA”) to issue them.   We could use an official certificate authority vendor, but since our IPSec members are all in our own organization we will make our own CA, for free, and under our control.   RHEL7 (or CentOS7) is assumed.   Choose a machine or virtual machine or cloud instance to be your CA;  it is of utmost importance that this machine is secure, and available, ie redundant.   The CA -must- be on a its own machine for security, then certs which it generates are distributed to network members.   The CA should be air-gapped, if we’re doing it right.

On the CA machine:

# yum install strongswan

RedHat has renamed the ipsec utility to ‘strongswan’, to differentiate it from the Libreswan utility.   Most instructions you’ll find out there start with ‘ipsec’, but if you’re running RHEL think strongswan.

Gen the CA’s private key:

# strongswan pki --gen --type rsa --outform pem --size 16384 > /etc/pki/CA/private/{CAmachinename}-CAkey.pem

(And then make a few phone calls, get a snack, chat with the receptionist, etc)   You should not store this private key of the CA on a host that has access to the Internet  —  it is the master key.   If nothing else, put on a USB or chip card which is removed when not needed.

Extract and self-sign the CA’s public certificate using the private key:

# strongswan pki --self --in /etc/pki/CA/private/{CAmachinename}-CAkey.pem --type rsa --san {domainname.tld} --dn "C=US, O={companyname}, CN={domainname.tld} CA" --outform pem --ca > /etc/pki/CA/certs/{CAmachinename}-CAcert.pem

Protect our private CA key:

# chmod -R 600 private

Now our shiny new CA is ready to issue end-entity certificates for members of our LAN.

For *each*peer* (all VPN clients and VPN gateways) gen a private key & matching cert, and sign using the new CA to prove authenticity.

# mkdir -Z /etc/pki/ipsec && cd /etc/pki/ipsec
# mkdir -Z private certs

Private key, machineA

# strongswan pki --gen --type rsa --outform pem --size 16384 > /etc/pki/ipsec/private/{machineA}-Key.pem

Check it

# strongswan pki --print --type priv --in /etc/pki/ipsec/private/{machineA}-Key.pem

Extract the public key and issue a cert for machineA:

# strongswan pki --pub --in /etc/pki/ipsec/private/{machineA}-Key.pem --type rsa | strongswan pki --issue --cacert /etc/pki/CA/certs/{CAmachinename}-CAcert.pem --cakey /etc/pki/CA/private/{CAmachinename}-CAkey.pem --san {machineA}.{domainname.tld} --dn "C=US, O={companyname}, CN={machineA}.{domainname.tld}" --outform pem > /etc/pki/ipsec/certs/{machineA}-Cert.pem

Note:   The LAN-resolvable domain name of the machine MUST be contained in the Subject Alternative Name (—-san), or else the connexion will fail, and it’s a good idea to put it in the Subject Distinguished Name (CN=, or Common Name).   I put it in both, just for fun…

Further, if this machine is an IPSec gateway, say between the LAN and internal printers or the LAN and outside Internet, you must set two —-san switches, one for the machine’s publicly resolvable {domainname.tld}, and the other for the machine’s LAN-resolvable {machineA}.{domainname.tld}.   Do not try to use one —-san and comma-separate the two identities, because you’re doing it wrong™.   For CN= only one resolvable name is allowed.

Check it — what you’re looking for on the public cert in particular is, subject: CN={machineA}.{domainname.tld} (set by —-dn), and altNames: {machineA}.{domainname.tld} (set by –san).   This is important so that this machine as responder can authenticate itself to the other.

# strongswan pki --print --in /etc/pki/ipsec/certs/{machineA}-Cert.pem
  subject:  "C=US O= CN={machineA}.{domainname.tld}"
  issuer:   "C=US, O={companyname}, CN={domainname.tld} CA"
  validity:  not before Mar 20 12:00:42 2018, ok
             not after  Mar 19 12:00:42 2021, ok (expires in 1094 days)
  serial:    53:39:02:39:32:f5:ae:a7
  altNames:  {domainname.tld}, {machineA}.{domainname.tld}
  authkeyId: 65:8d:ab:ea:ef:72:57:e2:5b:82:86:61:1e:91:b3:2b:f0:3d:a3:f9
  subjkeyId: 36:18:07:a0:1d:db:9a:d0:d2:04:7d:38:a1:84:6e:a3:37:35:de:42
  pubkey:    RSA 16384 bits
  keyid:     d7:e8:1e:e4:04:2b:f1:c9:29:21:7e:55:d1:d5:65:fc:9d:43:1f:3c
  subjkey:   36:18:07:a0:1d:db:9a:d0:d2:04:7d:38:a1:84:6e:a3:37:35:de:42

Private key, machineB

# strongswan pki --gen --type rsa --outform pem --size 16384 > /etc/pki/ipsec/private/{machineB}-Key.pem

Check it.

Extract the public key and issue a cert for machineB:

# strongswan pki --pub --in /etc/pki/ipsec/private/{machineB}-Key.pem --type rsa | strongswan pki --issue --cacert /etc/pki/CA/certs/{CAmachinename}-CAcert.pem --cakey /etc/pki/CA/private/{CAmachinename}-CAkey.pem --san {machineB}.{domainname.tld} --dn "C=US, O={companyname}, CN={machineB}.{domainname.tld}" --outform pem > /etc/pki/ipsec/certs/{machineB}-Cert.pem

Check it.

… etc.

Protect our private keys:

# chmod -R 600 private

Install strongswan on each member machine in the LAN, then *securely* distribute each machine’s private key to the corresponding peer, perhaps by USB drive, or via scp.  (SSH)   Don’t email them;   nope don’t email them.   Always assume that an adverse party is listening in on the LAN  —  if they’re doing so by mirroring a switch port, they’re about to get screwed as everything will be encrypted!   Each machine-specific key will go in to /etc/pki/ipsec/private/ for its machine.
Remember to:

# chmod -R 600 /etc/pki/ipsec/private

Then the *public* cert of each member machine must be imported to its respective /etc/pki/ipsec/certs/, and symlinked to /etc/strongswan/swanctl/x509/.   There is no need to put the public certs of all member machines into all other member machines, as our certs are kindly signed by our own Certificate Authority and can be authenticated through that trust mechanism.   The member machines only need the CA certificate (in /etc/pki/CA/certs/ and symlinked to /etc/strongswan/swanctl/x509ca/) to authenticate all peers which provide a valid certificate that is signed by our duly authorized CA.   In order to prevent man-in-the-middle attacks the identity claimed by the peer must be confirmed by the certificate, either by the subject or a subjectAltName extension, in our case by the SAN.

For those of us who run SELinux (as we all should be), on each machine:
# restorecon -FRv /etc/pki && restorecon -FRv /etc/strongswan

Similarly, the CA machine’s *public* certificate (/etc/pki/CA/cacerts/{CAmachinename}-CAcert.pem) must be distributed to each member machine into /etc/pki/CA/certs/
… the CA’s private key must never be distributed outside the CA machine.

Even though these certs are host-based, as time goes on there will be a need to revoke certs.

# strongswan pki --signcrl --cacert /etc/pki/CA/certs/{CAmachinename}-CAcert.pem --cakey /etc/pki/CA/private/{CAmachinename}-CAkey.pem --reason superseded --cert /etc/pki/ipsec/certs/{machine?}-Cert.pem > /etc/pki/CA/crl/{CAmachinename}-CRL.pem

To bundle up the key, cert, and CA cert into a package suitable for import into other apps, like the Android Strongswan app:

# openssl pkcs12 -in /etc/pki/ipsec/certs/{machine?}-Cert.pem -inkey /etc/pki/ipsec/private/{machine?}-Key.pem -certfile /etc/pki/CA/certs/{CAmachinename}-CAcert.pem -export -out /etc/pki/ipsec/{machine?}.p12

Keep in mind that an X.509 cert is an X.509 cert is an X.509 cert, and we have put ours in the proper location under Posix standards.   So you can use these keys/certs also for other encryption purposes by setting their location in the application’s config file.   The only occasion where this is not recommended is when the application must interact with entities outside the organization  —  a good example of this is Postfix, to receive and deliver email.   It has to communicate with other indeterminate mail servers to exchange email.   Another example is with your web server.   For these you want a generally recognized CA to sign the cert, so use a public CA like the free LetsEncrypt, which is sponsored by all the right people.

~~   Setting Up Strongswan   ~~

Now it’s time to set up Strongswan on each of the LAN members.   The Strongswan documentation is pretty chaotic, and one or two outspoken ones on #IRC are wise guys, but here’s the truth of it:   Strongswan’s job is to set up the connexions;   it does not set up subnets, and it does not encrypt.   It configures the kernel to encrypt traffic based on a ‘traffic selector‘.   We need only strongswan-swanctl.service running on each member, and host-to-host configurations.   We will use Transport mode, so it encrypts data between IP addresses of the members

At last count there were 371 principal ways to configure Strongswan, and this isn’t considering the customization that can be done.   As Samuel Johnson said, “The prospect of being hanged focuses the mind wonderfully.”   So to restate our goal clearly:  we will configure our LAN for universal encryption, and will allow machines outside the LAN to participate as if they were inside, transparently.

We are setting things up the new and most advanced way, ie for Strongswan ≥ version 5.2 with the swanctl command and vici interface.   This is in contrast with the older way, which is with ipsec.conf and ipsec.secrets configuration files and legacy ipsec stroke interface.

Let’s start by symlinking our certificates created above for each machine, into the correct swanctl subdirectories.   Remember, we’d created our private and public certs in the system general PKI directory, so now we’re going to link them in to Strongswan, and swanctl will automatically know where to find them.

# cd /etc/strongswan/swanctl
# ln -s /etc/pki/CA/certs/{CAmachinename}-CAcert.pem x509ca/
# ln -s /etc/pki/ipsec/private/{machine?}-Key.pem private/
# ln -s /etc/pki/ipsec/certs/*.pem x509/

Do this on each member machine.

The new swanctl method does not do anything with ipsec files, so don’t worry about them.

In this example, initiator and respondent are in the subnet, but you will set this to the CIDR of your own LAN.   


connections {
    trap-any {
        remote_addrs = %any
        local {
            auth = psk
        remote {
            auth = psk

        children {
            trap-yn {
                remote_ts =
                local_ts =
                mode = transport
                start_action = trap

90% of IPSec problems I see are caused by ‘traffic selectors‘  —  that is local_ts and remote_ts.   If traffic does not match the traffic selectors, it is passed UNencrypted, IOW in this case machines communicating within the LAN will be encrypted, but a machine asking for an IP outside the LAN will be passed to the Gateway and out to The Internets, unencrypted.   Just be aware that there could be infosec leaks due to traffic selectors.

Now, start_action = trap means that we are capturing this machine for VPN use only, so it will be uncommunicative with civilian machines.   So for devices like printers, access points, switches, Zwave controllers, etc which do not have IPSec/IKE2 support, there must be a gateway which lives in both VPN and non-VPN worlds.   This can be a cloud instance in your LAN, and I prefer to do this rather than put the IPSec gateway also in the WAN firewall.   This way if the WAN gateway is ever compromised, they aren’t already inside my IPSec gateway also.   ‘Security by obscurity’?   No, tell anyone who blurts this out that Security Is Layering.  Full stop.

For your firewall it’s not enough to just open UDP ports 500 and 4500 in and out.   IPSec needs special cosseting, and in my case that would be with Shorewall, which I’ve used for many years.   I run Shorewall on every (virtual)machine so each is protected from others in case of a ham-handed breach.

Are we running SELinux?  (We should be)   On each machine if:
# getenforce

# restorecon -FRv /etc/strongswan
# restorecon -FRv /etc/pki

(Restore the default SELinux security context, recursively)
And just to be sure, enable logging of all SELinux events:
# semodule -DB

Enable and start the daemon on each machine:

# systemctl enable strongswan-swanctl && systemctl start strongswan-swanctl

Better check it:

# systemctl status strongswan-swanctl
 strongswan-swanctl.service - strongSwan IPsec IKEv1/IKEv2 daemon using swanctl
   Loaded: loaded (/usr/lib/systemd/system/strongswan-swanctl.service; enabled; vendor preset: disabled)
   Active: active (running) since Sat 2018-02-24 11:18:27 PDT; 5s ago
  Process: 49205 ExecStartPost=/usr/sbin/swanctl --load-all --noprompt (code=exited, status=0/SUCCESS)
 Main PID: 49186 (charon-systemd)
   Status: "charon-systemd running, strongSwan 5.5.3, Linux 4.13.0-1.el7.elrepo.x86_64, x86_64"
   CGroup: /system.slice/strongswan-swanctl.service
           └─49186 /usr/sbin/charon-systemd

Mar 11 11:18:27 swanctl[49205]: opening directory '/etc/strongswan/swanctl/private' failed: Permission denied
Mar 11 11:18:27 swanctl[49205]: opening directory '/etc/strongswan/swanctl/rsa' failed: Permission denied
Mar 11 11:18:27 swanctl[49205]: opening directory '/etc/strongswan/swanctl/ecdsa' failed: Permission denied
Mar 11 11:18:27 swanctl[49205]: opening directory '/etc/strongswan/swanctl/bliss' failed: Permission denied
Mar 11 11:18:27 swanctl[49205]: opening directory '/etc/strongswan/swanctl/pkcs8' failed: Permission denied
Mar 11 11:18:27 swanctl[49205]: opening directory '/etc/strongswan/swanctl/pkcs12' failed: Permission denied
Mar 11 11:18:27 swanctl[49205]: no authorities found, 0 unloaded
Mar 11 11:18:27 swanctl[49205]: no pools found, 0 unloaded
Mar 11 11:18:27 swanctl[49205]: no connections found, 0 unloaded
Mar 11 11:18:27 systemd[1]: Started strongSwan IPsec IKEv1/IKEv2 daemon using swanctl.

Опять проклятый SELinux,   er I mean,   Again damn SELinux…   well what’s wrong?

# audit2allow -i /var/log/audit/audit.log

#============= ipsec_mgmt_t ==============
allow ipsec_mgmt_t ipsec_conf_file_t:dir read;

FFS, clearly an SELinux problem since it goes away when we disable it.   We’re going to have to manually make an exception module, since of course we love SELinux.

CAUTION:  Science Content

~~   Taming SELinux   ~~

SELinux can be confounding and difficult, and the most wonderful thing, at different times of course and usually the former.   But don’t disable SELinux.

There are many ‘easy’ ways to determine what the SELinux problem is, including several in # man audit2allow.   But the only safe way of fixing SELinux problems is to actually do the analysis and fix the correct problem.

We know from above that there was some problem opening a directory.   And we know that SELinux is to blame because the error goes away when we disable it.   Let’s get some detail.
# ausearch -m avc,user_avc,selinux_err -ts today
… so we are searching /var/log/audit/audit.log, for 3 classes of error, which happened today (when we started strongswan-swanctl), and it responds:

time->Sat Feb 24 11:25:17 2018
type=PROCTITLE msg=audit(1520191517.404:14449): proctitle=2F7573722F62696E2F73797374656D642D746D7066696C6573002D2D636C65616E type=SYSCALL msg=audit(1520191517.404:14449): arch=c000003e syscall=54 success=no exit=-1 a0=3 a1=1 a2=20 a3=7fff2f92e74c items=0 ppid=1 pid=32716 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm=”systemd-tmpfile” exe=”/usr/bin/systemd-tmpfiles” subj=system_u:system_r:systemd_tmpfiles_t:s0 key=(null) type=AVC msg=audit(1520191517.404:14449): avc: denied { net_admin } for pid=32716 comm=”systemd-tmpfile” capability=12 scontext=system_u:system_r:systemd_tmpfiles_t:s0 tcontext=system_u:system_r:systemd_tmpfiles_t:s0 tclass=capability permissive=0

This is about a systemd process  —  unrelated to our issue.   A process must have the right security context, to access a file or directory which has its own security context.
time->Sat Feb 24 11:35:24 2018
type=USER_AVC msg=audit(1520192124.607:14456): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg=’avc: received policyload notice (seqno=3) exe=”/usr/lib/systemd/systemd” sauid=0 hostname=? addr=? terminal=?’

Not an error.
time->Sat Feb 24 11:48:27 2018 type=PROCTITLE msg=audit(1520792307.853:7361): proctitle=2F7573722F7362696E2F7377616E63746C002D2D6C6F61642D616C6C002D2D6E6F70726F6D7074 type=PATH msg=audit(1520792307.853:7361): item=0 name=”/etc/strongswan/strongswan.conf” nametype=UNKNOWN cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0 type=CWD msg=audit(1520792307.853:7361): cwd=”/” type=SYSCALL msg=audit(1520792307.853:7361): arch=c000003e syscall=4 success=no exit=-13 a0=7ffd5a137e10 a1=7ffd5a137f50 a2=7ffd5a137f50 a3=63 items=1 ppid=1 pid=49205 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm=”swanctl” exe=”/usr/sbin/swanctl” subj=system_u:system_r:ipsec_mgmt_t:s0 key=(null) type=AVC msg=audit(1520792307.853:7361): avc: denied { search } for pid=49205 comm=”swanctl” name=”strongswan” dev=”dm-0″ ino=16809724 scontext=system_u:system_r:ipsec_mgmt_t:s0 tcontext=system_u:object_r:ipsec_conf_file_t:s0 tclass=dir permissive=0

Uh oh, this is relevant.   We have success=no, pid=49205 (processID), uid=0 gid=0 (root), exe=”/usr/sbin/swanctl” (the process trying to access), avc: denied { search } (a search of a dir was denied), name=”strongswan” (/etc/strongswan/, the dir it tried to access), dev=”dm-0″ (on this device), tcontext=system_u:object_r:ipsec_conf_file_t:s0 (the target context, ie the security context it wanted to see on the dir but did not), tclass=dir (the target class is a directory), and permissive=0 (SELinux is running in Enforcing mode).   See?   Easy.   You might see this 20 more times or so.

But the thing is, /usr/sbin/swanctl was trying to read a directory where its context didn’t match, and it dumps out from trying to read config files and certs right there.   There may be other yard bombs in this Easter egg hunt.   So let’s find the extent of the problems by putting SELinux in Permissive mode and trying again.   Permissive logs errors like Enforcing, but it does not block things.
# setenforce 0
# systemctl restart strongswan-swanctl

… and quick before anything else logs an error:
# ausearch -m avc,user_avc,selinux_err -ts today

time->Sat Feb 24 13:21:21 2018
type=PROCTITLE msg=audit(1520799681.363:30519): proctitle=2F7573722F7362696E2F7377616E63746C002D2D6C6F61642D616C6C002D2D6E6F70726F6D7074 type=PATH msg=audit(1520799681.363:30519): item=0 name=”/etc/strongswan/strongswan.d/charon” node=33669295 dev=fd:00 mode=040755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:ipsec_conf_file_t:s0 nametype=NORMAL cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0 type=CWD msg=audit(1520799681.363:30519): cwd=”/” type=SYSCALL msg=audit(1520799681.363:30519): arch=c000003e syscall=257 success=yes exit=4 a0=ffffffffffffff9c a1=7ffc6becfe50 a2=90800 a3=0 items=1 ppid=1 pid=49423 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm=”swanctl” exe=”/usr/sbin/swanctl” subj=system_u:system_r:ipsec_mgmt_t:s0 key=(null) type=AVC msg=audit(1520799681.363:30519): avc: denied { open } for pid=49423 comm=”swanctl” path=”/etc/strongswan/strongswan.d/charon” dev=”dm-0″ ino=33669295 scontext=system_u:system_r:ipsec_mgmt_t:s0 tcontext=system_u:object_r:ipsec_conf_file_t:s0 tclass=dir permissive=1 type=AVC msg=audit(1520799681.363:30519): avc: denied { read } for pid=49423 comm=”swanctl” name=”charon” dev=”dm-0″ ino=33669295 scontext=system_u:system_r:ipsec_mgmt_t:s0 tcontext=system_u:object_r:ipsec_conf_file_t:s0 tclass=dir permissive=1
time->Sat Feb 24 13:21:21 2018
type=PROCTITLE msg=audit(1520799681.397:30520): proctitle=2F7573722F7362696E2F7377616E63746C002D2D6C6F61642D616C6C002D2D6E6F70726F6D7074 type=PATH msg=audit(1520799681.397:30520): item=0 name=”/etc/strongswan/swanctl/x509/cygnus-Cert.pem” inode=887377 dev=fd:00 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:cert_t:s0 nametype=NORMAL cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0 type=CWD msg=audit(1520799681.397:30520): cwd=”/” type=SYSCALL msg=audit(1520799681.397:30520): arch=c000003e syscall=4 success=yes exit=0 a0=55d29835ac00 a1=7ffc6bed11b0 a2=7ffc6bed11b0 a3=1 items=1 ppid=1 pid=49423 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm=”swanctl” exe=”/usr/sbin/swanctl” subj=system_u:system_r:ipsec_mgmt_t:s0 key=(null) type=AVC msg=audit(1520799681.397:30520): avc: denied { read } for pid=49423 comm=”swanctl” name=”cygnus-Cert.pem” dev=”dm-0″ ino=50346842 scontext=system_u:system_r:ipsec_mgmt_t:s0 tcontext=system_u:object_r:ipsec_conf_file_t:s0 tclass=lnk_file permissive=1

What’s important here is we now have an additional error, on a symlink file called /etc/strongswan/swanctl/x509/cygnus-Cert.pem.   Remember, we’d earlier done a:
# restorecon -FRv /etc/strongswan
… which had restored what RedHat thinks are the proper SELinux security contexts in that directory tree.   But, it has gotten it wrong, and that is a bug in RedHat.   And if one symlink is mischaracterized, they all are.   So let’s fix this:
# setenforce 1
# mkdir /usr/local/src/selinux && cd /usr/local/src/selinux
# ausearch -m avc,user_avc,selinux_err -ts today | audit2allow -M strongswan; sudo semodule -i strongswan.pp

What did we just do here?   We made a new directory where we can keep all the SELinux modules we create, for archival purposes.   Then we searched /var/log/audit/audit.log for all violations of avc,user_avc,selinux_err, which happened today.   And we plugged those right in to our new SELinux module called strongswan(.te).  (check it, if you don’t believe me)   Finally we installed that new module into the SELinux module store so it would be permanently present there.   You must be in the module directory for the ausearch command to work.

Mistakes can be undone with:
# semodule -r {modulename}

But did it work?
# getenforce
# systemctl restart strongswan-swanctl
# systemctl status strongswan-swanctl
strongswan-swanctl.service – strongSwan IPsec IKEv1/IKEv2 daemon using swanctl
Loaded: loaded (/usr/lib/systemd/system/strongswan-swanctl.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2018-02-24 14:31:29 PDT; 5s ago
Process: 49545 ExecStartPost=/usr/sbin/swanctl –load-all –noprompt (code=exited, status=0/SUCCESS)
Main PID: 49527 (charon-systemd)
Status: “charon-systemd running, strongSwan 5.5.3, Linux 4.13.0-1.el7.elrepo.x86_64, x86_64”
CGroup: /system.slice/strongswan-swanctl.service
└─49527 /usr/sbin/charon-systemd

Feb 24 14:31:29 swanctl[49545]: loaded certificate from ‘/etc/strongswan/swanctl/x509/antilia-Cert.pem’
Feb 24 14:31:29 swanctl[49545]: loaded certificate from ‘/etc/strongswan/swanctl/x509/aries-Cert.pem’
Feb 24 14:31:29 swanctl[49545]: loaded certificate from ‘/etc/strongswan/swanctl/x509/canis-Cert.pem’
Feb 24 14:31:29 swanctl[49545]: loaded certificate from ‘/etc/strongswan/swanctl/x509/equuleus-Cert.pem’
Feb 24 14:31:29 swanctl[49545]: loaded certificate from ‘/etc/strongswan/swanctl/x509/hydrus-Cert.pem’
Feb 24 14:31:29 swanctl[49545]: loaded certificate from ‘/etc/strongswan/swanctl/x509/lepus-Cert.pem’
Feb 24 14:31:29 swanctl[49545]: loaded certificate from ‘/etc/strongswan/swanctl/x509/octans-Cert.pem’
Feb 24 14:31:29 swanctl[49545]: loaded certificate from ‘/etc/strongswan/swanctl/x509/perseus-Cert.pem’
Feb 24 14:31:29 swanctl[49545]: loaded certificate from ‘/etc/strongswan/swanctl/x509ca/blackhole-CAcert.pem’
Feb 24 14:31:29 swanctl[49545]: loaded private key from ‘/etc/strongswan/swanctl/private/cygnus-Key.pem’

# lsof -i -n -P

charon-sy 49527 root 11u IPv6 819852 0t0 UDP *:500
charon-sy 49527 root 12u IPv6 819853 0t0 UDP *:4500
charon-sy 49527 root 13u IPv4 819854 0t0 UDP *:500
charon-sy 49527 root 14u IPv4 819855 0t0 UDP *:4500
charon-sy 49527 root 22u IPv4 819873 0t0 UDP *:68

Sure did.

Bottom line:   The default policy for SELinux did not set /etc/strongswan/ to match the security context of its daemon, and did not take into account that there might be symlinks in /etc/strongswan/swanctl/.   So I’ve filed a bug with redhat -> selinux-policy-targeted.

Ok even though our daemon is running now, it does not mean that it is running properly.   Check it with:
# swanctl -L

If you get nothing, your configuration was not fully loaded from /etc/strongswan/swanctl/swanctl.conf.   Since the machine does not have its full config loaded it has no config to compare with attempted incoming connexions, so if you try that you will get in the log my favorite “NO_PROPOSAL_CHOSEN“.   You now have two choices. You can either:

  • Have an aneurysm, or
  • Fix it



~~   Changing Ports   ~~

I like to change the default listening ports for some daemons to avoid detection.   Some will say “well that’s Security Through Obscurity and that isn’t good”, but apparently they’ve never looked at what their firewall is actually DROPping.   Hundreds of bots, hammering away at the same old ports every minute, as if it will make a difference.

Ne’er do wells who Cry ‘Havoc!’, and let slip the dogs of war with their worms and ‘bots, are busy hitting as many IPs as they can.   They are looking for low-hanging fruit and never scan all privileged ports (much less all ports) on every IP they visit.   This would happen only with a targeted attack, and changing ports up to say, 44500 and 45500 is a reasonable measure in case there’s some vuln in Strongswan.   And we can do this, since we are only talking amongst ourselves.   True security is about layering different methodologies.   The really sensitive could also add port knocking.

Changing ports is easy, and there are a number of other interesting options to modify Strongswan’s charon daemon.   Edit /etc/strongswan/strongswan.d/charon.conf and search for port = and port_nat_t =.   Uncomment them and set to numbers which make sense to you.   Just make sure to set all members to these numbers, and open these UDP ports incoming in your firewall for each machine.   Restart the daemon and you’re in a new place.

~~   Other Settings   ~~

Some other /etc/strongswan/strongswan.d/charon.conf settings I like:

# Discard certificates with unsupported or unknown critical extensions.
enforce_critical = yes

# Enable Denial of Service protection using cookies and aggressiveness checks.
dos_protection = yes

Now, for remote systems:

Roadwarrior ipsec.conf:
conn %default

conn RU1_TI_1

This is a passthrough policy that applies to packets for which all of the section’s conditions are true:

For received packets:
      The recipient is in
      The sender is in
For sent packets:
      The recipient is in
      The sender is in

Note that the conditions for received and sent packets are simply the inverse of each other.

Again, left is set to to prevent this connexion from being considered in the conn lookup when a peer tries to connect, and to prevent strongSwan from switching the sides of the conn (because is a local IP address).   Don’t worry, just stick with the knitting.


# ipsec status and statusall

conn passthrough-2
    # Make sure those conns are excluded from every conn selection
    # Our LAN IP address range
    # These two lines are critical.

Since we’re using the new way (swanctl.conf style configurations) it is not an issue, so remote_addrs or local_addrs can be set to to prevent strongSwan from considering the conn in the conn lookup when a peer tries to connect.   In this example, only remote_addrs is set to   You are free to choose local_addrs, remote_addrs or both.


connections {
    passthrough-2 {
        remote_addrs =
        children {
            passthrough-2 {
                local_ts =
                remote_ts =
                mode = pass
                start_action = trap

And now for specific protocols or ports, the following configuration example is for traffic to the local SSH port:


# ipsec status and statusall

conn passthrough-ssh
    # Make sure those conns are excluded from every conn selection
    left =
    leftsubnet = %dynamic[tcp/22]
    rightsubnet =
    type = passthrough
    auto = route


connections {
    passthrough-ssh {
        remote_addrs =
        children {
            passthrough-ssh {
                local_ts = dynamic[tcp/22]
                remote_ts =
                mode = pass
                start_action = trap

Ok so now that we have the configuration files set up on all the members of our LAN, as well as external members:

# systemctl enable strongswan-swanctl.service && systemctl start strongswan-swanctl.service

You will notice that there is also a strongswan.service and a nm-strongswan-service.conf in the Strongswan rpm package.   The former is for the older way of doing business (which we are not doing), and the latter is a helper if you are running NetworkMangler.

,'after' => '

') )