-
-
Save xpertdev/ee3b1e079250c7d6b5737ed9d3daee09 to your computer and use it in GitHub Desktop.
Revisions
-
andrewlkho revised this gist
Jan 17, 2017 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -78,7 +78,8 @@ Install dnscrypt-proxy. $ cd /usr/local/src $ curl -LO https://download.dnscrypt.org/dnscrypt-proxy/dnscrypt-proxy-1.9.2.tar.bz2 $ gpg --recv-keys 2B6F76DA $ curl https://download.dnscrypt.org/dnscrypt-proxy/dnscrypt-proxy-1.9.2.tar.gz.sig | \ > gpg --verify - ./dnscrypt-proxy-1.9.2.tar.gz $ tar xjf dnscrypt-proxy-1.9.2.tar.gz && cd dnscrypt-proxy-1.9.2 $ ./configure --prefix=/usr/local $ make -
andrewlkho revised this gist
Jan 17, 2017 . 1 changed file with 88 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -64,7 +64,89 @@ Before getting started with configuring strongSwan, you'll want to generate an I First subnet: fdf3:5237:bf63::/64 Last subnet: fdf3:5237:bf63:ffff::/64 Clearly your prefix will not be the same as that, so substitute `fdf3:5237:bf63::/64` in the dnsmasq, strongSwan and iptables configuration below with what you have. Optional: secure DNS with dnscrypt and DNSSEC ============================================= To prevent DNS cache poisoning, I run a local DNS server on `debian` which the VPN clients use. This consists of a [dnscrypt-proxy](https://github.com/jedisct1/dnscrypt-proxy/wiki) client bound to [::1]:5353 which transparently proxies queries through to a dnscrypt-aware upstream resolver. dnscrypt-proxy itself is upstream of [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html) which provides features like DNSSEC validation and is what the VPN clients have configured as their DNS server. Install dnscrypt-proxy. $ sudo apt-get install libsodium-dev libldns-dev $ cd /usr/local/src $ curl -LO https://download.dnscrypt.org/dnscrypt-proxy/dnscrypt-proxy-1.9.2.tar.bz2 $ gpg --recv-keys 2B6F76DA $ curl https://download.dnscrypt.org/dnscrypt-proxy/dnscrypt-proxy-1.9.2.tar.gz.sig | gpg --verify - ./dnscrypt-proxy-1.9.2.tar.gz $ tar xjf dnscrypt-proxy-1.9.2.tar.gz && cd dnscrypt-proxy-1.9.2 $ ./configure --prefix=/usr/local $ make $ make install Create an unprivileged user. $ useradd --system -d /usr/local/lib/dnscrypt-proxy -s /usr/sbin/nologin dnscrypt Edit `/usr/local/etc/dnscrypt-proxy.conf`. You can choose whichever dnscrypt-enabled upstream server you want; I have chosen to use [DNSCrypt.eu](https://dnscrypt.eu/) of which their Netherlands server has the fewest hops to `debian`. dnscrypt-proxy is bound to ::1 port 5353. ProviderName 2.dnscrypt-cert.resolver1.dnscrypt.eu ProviderKey 67C0:0F2C:21C5:5481:45DD:7CB4:6A27:1AF2:EB96:9931:40A3:09B6:2B8D:1653:1185:9C66 ResolverAddress [2a00:d880:3:1::a6c1:2e89]:443 Daemonize no LocalAddress [::1]:5353 LocalCache off User dnscrypt EphemeralKeys on BlockIPv6 no Copy across the systemd service (amending the paths) and start dnscrypt-proxy. $ sed -e 's:^ExecStart=.*$:ExecStart=/usr/local/sbin/dnscrypt-proxy /usr/local/etc/dnscrypt-proxy.conf:' \ > /usr/local/src/dnscrypt-proxy-1.9.2/dnscrypt-proxy.service > /etc/systemd/system/dnscrypt-proxy.service $ systemctl enable dnscrypt-proxy.service $ systemctl start dnscrypt-proxy You can check that it works by querying `resolver.dnscrypt.org` which returns the address of the nameserver you are using. $ dig @::1 -p 5353 +short -x $( dig @::1 -p 5353 +short resolver.dnscrypt.org A ) resolver1.dnscrypt.eu The next step is to install dnsmasq. $ apt-get install dnsmasq dnsmasq should bind to ::1 and also a unique local address on the loopback interface. Use the ULA prefix generated previously, but a different subnet, by putting the following into `/etc/network/interfaces`. auto lo:1 iface lo:1 inet6 static address fdf3:5237:bf63:1::1 netmask 64 autoconf 1 Then bring it up with `ifup lo:1`. Edit `/etc/dnsmasq.conf`. no-resolv no-hosts server=::1#5353 listen-address=::1 listen-address=fdf3:5237:bf63:1::1 bind-interfaces dnssec trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5 dnssec-check-unsigned bogus-priv domain-needed stop-dns-rebind rebind-localhost-ok cache-size=2000 Restart dnsmasq. $ systemctl restart dnsmasq Configure strongSwan @@ -107,7 +189,7 @@ Copy the following `/etc/ipsec.conf` (don't forget to change the ULA). right=%any rightauth=pubkey rightsourceip=172.16.0.0/24,fdf3:5237:bf63::/64 rightdns=fdf3:5237:bf63:1::1 conn ikev2-pubkey auto=add @@ -116,7 +198,7 @@ A few points to note on that: - I have only allowed a single IKE cipher suite. If you want to support clients other than macOS and iOS, you may need to adjust this. - macOS/iOS will only propose 128-bit AES-GCM if you configure the VPN using a `.mobileconfig` configuration profile. If you use the GUI to configure the VPN on the client then you will need to use `ike=aes256-sha2_256-prfsha256-ecp256!` and `esp=aes256-sha2_256-ecp256!`. - I have used the local DNS server bound to the loopback interface. Next, copy the following `/etc/ipsec.secrets`. @@ -175,6 +257,9 @@ Here is a snippet of my `/etc/iptables/rules.v6` (don't forget to change the ULA -A INPUT -p udp -m multiport --dports 500,4500 -j ACCEPT -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT -A FORWARD -m conntrack --ctstate NEW -s fdf3:5237:bf63::/64 -m policy --pol ipsec --dir in -j ACCEPT # If you are running a local DNS server as above -A INPUT -p udp --dport 53 -d fdf3:5237:bf63:1::1 -j ACCEPT COMMIT *nat -
andrewlkho revised this gist
Jan 17, 2017 . 1 changed file with 4 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -161,9 +161,9 @@ Here is a snippet of my `/etc/iptables/rules.v4`. *nat [...] -A POSTROUTING -s 172.16.0.0/24 -m policy --pol none --dir out -j MASQUERADE # If you have a static IP address you can do: # -A POSTROUTING -s 172.16.0.0/24 -m policy --pol none --dir out -j SNAT --to-source 203.0.113.1 COMMIT Here is a snippet of my `/etc/iptables/rules.v6` (don't forget to change the ULA). @@ -179,9 +179,7 @@ Here is a snippet of my `/etc/iptables/rules.v6` (don't forget to change the ULA *nat [...] -A POSTROUTING -s fdf3:5237:bf63::/64 -m policy --pol none --dir out -j MASQUERADE COMMIT -
andrewlkho revised this gist
Jan 16, 2017 . 1 changed file with 6 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -161,7 +161,9 @@ Here is a snippet of my `/etc/iptables/rules.v4`. *nat [...] -A POSTROUTING -s 172.16.0.0/24 -m policy --pol none --dir out -j SNAT --to-source 203.0.113.1 # If you don't have a static IP address you can do: #-A POSTROUTING -s 172.16.0.0/24 -m policy --pol none --dir out -j MASQUERADE COMMIT Here is a snippet of my `/etc/iptables/rules.v6` (don't forget to change the ULA). @@ -177,7 +179,9 @@ Here is a snippet of my `/etc/iptables/rules.v6` (don't forget to change the ULA *nat [...] -A POSTROUTING -s fdf3:5237:bf63::/64 -m policy --pol none --dir out -j SNAT --to-source 2001:db8::1 # If you don't have a static IP address you can do: #-A POSTROUTING -s fdf3:5237:bf63::/64 -m policy --pol none --dir out -j MASQUERADE COMMIT -
andrewlkho renamed this gist
Jan 7, 2017 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
andrewlkho created this gist
Jan 7, 2017 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,212 @@ With heightening concern regarding the state of internet privacy (fuelled in part by the passing of the Investigatory Powers Act in the UK), I have set up a VPN server on the virtual server I have hosted with [Mythic Beasts](https://www.mythic-beasts.com/). This uses [strongSwan](https://strongswan.org/) and certificate-based IKEv2 authentication. Assumptions: - Debian Jessie server already set up and accessible via `debian.example.com`, a public IPv4 of `203.0.113.1` and a public IPv6 of `2001:db8::1` - Client username of `me` - Clients are running the latest versions of macOS and iOS (Sierra and 10 respectively at the time of writing) - No need to support any other operating systems (although the setup is easily translated) For automated deployment of a similar setup, albeit Ubuntu-based and using ansible for deployment, I recommend you take a look at [Algo VPN](https://github.com/trailofbits/algo). I used that project as a basis for my configuration. Install strongSwan ================== Most of the rest of this guide assumes that you are on the server with root permissions, so: % ssh debian.example.com % sudo -s $ apt-get install strongswan Build the public key infrastructure =================================== All of the certificates are stored in `/etc/ipsec.d`. Unfortunately, macOS Sierra does not seem to like PKI built using ECDSA certificates for reasons which are not clear to me so I have used 4096-bit RSA keys. The first step is to create a self-signed root CA certificate. $ cd /etc/ipsec.d $ ipsec pki --gen --type rsa --size 4096 --outform pem > private/ca.pem $ ipsec pki --self --ca --lifetime 3650 --in private/ca.pem \ > --type rsa --digest sha256 \ > --dn "CN=debian.example.com" \ > --outform pem > cacerts/ca.pem Next, generate a private key and signed certificate for the server. macOS requires the hostname/address in subjectAltName. Versions of Mac OS X prior to 10.7.4 required `--flag ikeIntermediate` but I have not added it here. $ ipsec pki --gen --type rsa --size 4096 --outform pem > private/debian.pem $ ipsec pki --pub --in private/debian.pem --type rsa | > ipsec pki --issue --lifetime 3650 --digest sha256 \ > --cacert cacerts/ca.pem --cakey private/ca.pem \ > --dn "CN=debian.example.com" \ > --san debian.example.com --san 203.0.113.1 --san 2001:db8::1 > --flag serverAuth --outform pem > certs/debian.pem The last certificate is for the client. You use one certificate for a single user on multiple devices hence I have only generated one. $ ipsec pki --gen --type rsa --size 4096 --outform pem > private/me.pem $ ipsec pki --pub --in private/me.pem --type rsa | > ipsec pki --issue --lifetime 3650 --digest sha256 \ > --cacert cacerts/ca.pem --cakey private/ca.pem \ > --dn "CN=me" --san me \ > --flag clientAuth \ > --outform pem > certs/me.pem Now that certificate generation is complete, you should remove the CA private key (`private/ca.pem`) from the server. You can either store it offline, or delete it entirely. If you choose the latter, you will not be able to sign any more peer certificates or [revoke a certificate](https://wiki.strongswan.org/projects/strongswan/wiki/SimpleCA#Certificate-Revocation-Lists-CRL) if a client were compromised. In the latter scenario, you would need to recreate a fresh PKI and disseminate to all peers. Failure to remove the CA private key means that anyone who gains access to it could MitM your TLS connections. Generate an IPv6 ULA ==================== Before getting started with configuring strongSwan, you'll want to generate an IPv6 [unique local address](https://en.wikipedia.org/wiki/Unique_local_address) block. The addresses are within the fc00::/7 block and contain a pseudo-random component according to [RFC 4193](https://tools.ietf.org/html/rfc4193). I've cobbled together a short script which will generate a ULA for you: % curl -s https://raw.githubusercontent.com/andrewlkho/ulagen/master/ulagen.py | python Prefix: fdf3:5237:bf63::/48 First subnet: fdf3:5237:bf63::/64 Last subnet: fdf3:5237:bf63:ffff::/64 Clearly your prefix will not be the same as that, so substitute `fdf3:5237:bf63::/64` in the strongSwan and iptables configuration below with what you have. Configure strongSwan ==================== Disable any plugins that you do not need. $ plugins=(aes gcm hmac kernel-netlink nonce openssl pem pgp \ > pkcs12 pkcs7 pkcs8 pubkey random revocation sha2 socket-default stroke x509) $ cd /etc/strongswan.d/charon $ for x in *.conf; do > if [[ ${plugins[(i)${x%.conf}]} -le ${#plugins} ]]; then > sed -E 's/^([[:space:]]+)load = no/\1load = yes/' ${x} > else > sed -E 's/^([[:space:]]+)load = yes/\1load = no/' ${x} > fi > done Copy the following `/etc/ipsec.conf` (don't forget to change the ULA). config setup uniqueids=never conn %default keyexchange=ikev2 ike=aes128gcm16-sha2_256-prfsha256-ecp256! esp=aes128gcm16-sha2_256-ecp256! fragmentation=yes rekey=no compress=yes dpdaction=clear left=%any leftauth=pubkey leftid=debian.example.com leftcert=debian.pem leftsendcert=always leftsubnet=0.0.0.0/0,::/0 right=%any rightauth=pubkey rightsourceip=172.16.0.0/24,fdf3:5237:bf63::/64 rightdns=2620:0:ccc::2,2620:0:ccd::2 conn ikev2-pubkey auto=add A few points to note on that: - I have only allowed a single IKE cipher suite. If you want to support clients other than macOS and iOS, you may need to adjust this. - macOS/iOS will only propose 128-bit AES-GCM if you configure the VPN using a `.mobileconfig` configuration profile. If you use the GUI to configure the VPN on the client then you will need to use `ike=aes256-sha2_256-prfsha256-ecp256!` and `esp=aes256-sha2_256-ecp256!`. - I have used the OpenDNS IPv6 resolvers Next, copy the following `/etc/ipsec.secrets`. : RSA debian.pem Then restart strongswan. $ systemctl restart strongswan Enable packet forwarding ======================== Configure the kernel to enable packet forwarding by putting the following lines in `/etc/sysctl.conf`. net.ipv4.ip_forward = 1 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv6.conf.all.forwarding = 1 net.ipv6.conf.eth0.accept_ra = 2 The penultimate line enables forwarding for IPv6, but has the unfortunate side-effect of therefore not accepting router advertisements. These are needed for SLAAC, without which the server cannot get routing information (at least, with how Mythic Beasts configure their virtual servers). This would break IPv6 networking on the server. The last line therefore adjusts this for the interface `eth0`. Load the settings. % sysctl -p Configure iptables ================== Here is a snippet of my `/etc/iptables/rules.v4`. *filter [...] -A INPUT -p esp -j ACCEPT -A INPUT -p ah -j ACCEPT -A INPUT -p udp -m multiport --dports 500,4500 -j ACCEPT -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT -A FORWARD -m conntrack --ctstate NEW -s 172.16.0.0/24 -m policy --pol ipsec --dir in -j ACCEPT COMMIT *nat [...] -A POSTROUTING -s 172.16.0.0/24 -m policy --pol none --dir out -j MASQUERADE COMMIT Here is a snippet of my `/etc/iptables/rules.v6` (don't forget to change the ULA). *filter [...] -A INPUT -p esp -j ACCEPT -A INPUT -m ah -j ACCEPT -A INPUT -p udp -m multiport --dports 500,4500 -j ACCEPT -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT -A FORWARD -m conntrack --ctstate NEW -s fdf3:5237:bf63::/64 -m policy --pol ipsec --dir in -j ACCEPT COMMIT *nat [...] -A POSTROUTING -s fdf3:5237:bf63::/64 -m policy --pol none --dir out -j MASQUERADE COMMIT Configure the clients ===================== To configure the macOS and iOS clients, you need to generate a configuration profile. I wrote a shell script to do this (`mobileconfiggen.sh`) which is attached to this gist. As well as the VPN settings, this pulls in the root CA certificate and client key/certificate pair. Aside from the variables at the start of the script, you will probably also want to amend the `OnDemandRules` array. This is an array of dictionaries, each of which specifies whether or not your iOS device will automatically connect to the VPN in certain scenarios. The rules I have specified mean that unless you are on a mobile connection or using one of the pre-specified trusted WiFi networks (`$TRUSTED_SSIDS`) it will connect to the VPN. If you want to edit this, then take a look at [Apple's Configuration Profile Reference](https://developer.apple.com/library/content/featuredarticles/iPhoneConfigurationProfileRef/Introduction/Introduction.html#//apple_ref/doc/uid/TP40010206-CH1-SW36). The script takes no arguments, and will output the configuration profile to STDOUT. $ ./mobileconfiggen.sh > debian.mobileconfig On macOS, you can install this with: $ profiles -I -F debian.mobileconfig On iOS, the easiest way to install it is to send the file to the device over AirDrop. Conclusion ========== That's it. Reboot your server to check it all comes up automatically and you should be done. A few links which were helpful to me: - [Algo VPN](https://github.com/trailofbits/algo): a similar setup based on deploying to an Ubuntu cloud server using ansible - [Andy Smith's blog](http://strugglers.net/~andy/blog/2011/09/04/linux-ipv6-router-advertisements-and-forwarding/): getting IPv6 packet forwarding and SLAAC to work together - [The strongSwan wiki](https://wiki.strongswan.org/projects/strongswan) - [Apple's Configuration Profile Reference](https://developer.apple.com/library/content/featuredarticles/iPhoneConfigurationProfileRef/Introduction/Introduction.html#//apple_ref/doc/uid/TP40010206-CH1-SW4) If you have any suggestions for how this guide or setup could be improved, then please [let me know](https://andrewho.co.uk/). This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,156 @@ #!/bin/zsh CLIENT="me" SERVER="debian" FQDN="debian.example.com" CA="ca" # WiFi SSIDs that do not require automatic connection to VPN on network change TRUSTED_SSIDS=("SSID1" "SSID2") PAYLOADCERTIFICATEUUID=$( cat /proc/sys/kernel/random/uuid ) PKCS12PASSWORD=$( cat /proc/sys/kernel/random/uuid ) cat << EOF <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>PayloadDisplayName</key> <string>${SERVER} VPN</string> <key>PayloadIdentifier</key> <string>${(j:.:)${(Oas:.:)FQDN}}</string> <key>PayloadUUID</key> <string>$( cat /proc/sys/kernel/random/uuid )</string> <key>PayloadType</key> <string>Configuration</string> <key>PayloadVersion</key> <integer>1</integer> <key>PayloadContent</key> <array> <dict> <key>PayloadDisplayName</key> <string>${SERVER} VPN</string> <key>PayloadDescription</key> <string>Configure VPN</string> <key>UserDefinedName</key> <string>${SERVER}</string> <key>VPNType</key> <string>IKEv2</string> <key>IKEv2</key> <dict> <key>RemoteAddress</key> <string>${FQDN}</string> <key>RemoteIdentifier</key> <string>${FQDN}</string> <key>LocalIdentifier</key> <string>${CLIENT}</string> <key>AuthenticationMethod</key> <string>Certificate</string> <key>PayloadCertificateUUID</key> <string>${PAYLOADCERTIFICATEUUID}</string> <key>CertificateType</key> <string>RSA</string> <key>ServerCertificateIssuerCommonName</key> <string>${FQDN}</string> <key>EnablePFS</key> <integer>1</integer> <key>IKESecurityAssociationParameters</key> <dict> <key>EncryptionAlgorithm</key> <string>AES-128-GCM</string> <key>IntegrityAlgorithm</key> <string>SHA2-256</string> <key>DiffieHellmanGroup</key> <integer>19</integer> </dict> <key>ChildSecurityAssociationParameters</key> <dict> <key>EncryptionAlgorithm</key> <string>AES-128-GCM</string> <key>IntegrityAlgorithm</key> <string>SHA2-256</string> <key>DiffieHellmanGroup</key> <integer>19</integer> </dict> <key>OnDemandEnabled</key> <integer>1</integer> <key>OnDemandRules</key> <array> <dict> <key>InterfaceTypeMatch</key> <string>WiFi</string> <key>SSIDMatch</key> <array> `for x in ${TRUSTED_SSIDS}; echo " <string>$x</string>"` </array> <key>Action</key> <string>Disconnect</string> </dict> <dict> <key>InterfaceTypeMatch</key> <string>Cellular</string> <key>Action</key> <string>Disconnect</string> </dict> <dict> <key>Action</key> <string>Connect</string> </dict> </array> </dict> <key>PayloadType</key> <string>com.apple.vpn.managed</string> <key>PayloadIdentifier</key> <string>com.apple.vpn.managed.${SERVER}</string> <key>PayloadUUID</key> <string>$( cat /proc/sys/kernel/random/uuid )</string> <key>PayloadVersion</key> <integer>1</integer> </dict> <dict> <key>PayloadDisplayName</key> <string>${CLIENT}.p12</string> <key>PayloadDescription</key> <string>Add PKCS#12 certificate</string> <key>PayloadCertificateFileName</key> <string>${CLIENT}.p12</string> <key>Password</key> <string>${PKCS12PASSWORD}</string> <key>PayloadContent</key> <data> $( openssl pkcs12 -export -inkey /etc/ipsec.d/private/${CLIENT}.pem -in /etc/ipsec.d/certs/${CLIENT}.pem -name "${CLIENT}" -certfile /etc/ipsec.d/cacerts/${CA}.pem -password pass:${PKCS12PASSWORD} | base64 ) </data> <key>PayloadType</key> <string>com.apple.security.pkcs12</string> <key>PayloadIdentifier</key> <string>com.apple.security.pkcs12.${CLIENT}</string> <key>PayloadUUID</key> <string>${PAYLOADCERTIFICATEUUID}</string> <key>PayloadVersion</key> <integer>1</integer> </dict> <dict> <key>PayloadDisplayName</key> <string>${SERVER} CA</string> <key>PayloadDescription</key> <string>Add CA root certificate</string> <key>PayloadCertificateFileName</key> <string>ca.pem</string> <key>PayloadContent</key> <data> $( cat /etc/ipsec.d/cacerts/${CA}.pem | base64 ) </data> <key>PayloadType</key> <string>com.apple.security.root</string> <key>PayloadIdentifier</key> <string>com.apple.security.root.${SERVER}</string> <key>PayloadUUID</key> <string>$( cat /proc/sys/kernel/random/uuid )</string> <key>PayloadVersion</key> <integer>1</integer> </dict> </array> </dict> </plist> EOF