Managing your gmail mailbox

I found out a way to get full control of my heavily loaded gmail mailbox… just plain code…without complicated looking (not easy to find) user menu’s to configure settings for archiving and cleaning my mailbox. Login to your gmail account (with your browser)…and then go to https://script.google.com/

Here you can put your (javascript) code and even debug it. Even better…after you are finished, you can expose this code as a (web)service or schedule it with the built in timer, woa …excellent dude!!!

Here is a snippet of the code I am using:

[javascript]

function cleanUp() {
var delayDays = 0; // Enter # of days before messages are moved to trash
var maxDate = new Date();
cleanupCandidates = ["meetup.com","alison.com","voordeelvanger.nl","email.campaign@sg.booking.com","alibaba@email.alibaba.com","linkedin.com","ezine.ns.nl","tix.nl","gorillasports.nl","tommyteleshopping.com","poldercasino.com","hortonworks.com","connect.wso2.com","implicit-explicit.com","geocaching.com","autodna.mail"];

maxDate.setDate(maxDate.getDate()-delayDays);
gthreads = GmailApp.getInboxThreads();
for (var fc=0; fc<cleanupCandidates.length; fc++){
for (var i=0; i<gthreads.length; i++){
messages = gthreads[i].getMessages();
for (var j=0; j<messages.length; j++){
if(messages[j].getFrom().indexOf(cleanupCandidates[fc])>-1){
if (messages[j].getDate()<=maxDate){
Logger.log("Message older than maxdate ("+delayDays+"days)…removing it: ");
Logger.log("THREAD ID"+gthreads[i].getId()+" FROM: "+messages[j].getFrom()+" subject: "+messages[j].getSubject());
messages[j].moveToTrash();
}
}
}
}
}
}

function labelStuff(){
archiveCandidates = ["slack.com","googleplay-noreply@google.com","microsoft.com","klm-mail.com","redhat.com","transip.nl","eve-dev1.datalinks.nl","eve-dev.datalinks.nl","bonque.nl","itaq.nl","email.apple.com","Niels Westmeijer <niels@eve.nu>"];
labelCandidate = ["Archief/eve","Archief/playstore","Archief/microsoft","Archief/reizen","Archief/redhat","Archief/hosting","Archief/hosting-sec","Archief/hosting-sec","Archief","Archief","Archief/iTunes","Archief/eve"];

gthreads = GmailApp.getInboxThreads();
for (var i=0; i<gthreads.length; i++){
messages = gthreads[i].getMessages();
if(messages.length!=null){
for (var j=0; j<messages.length; j++){
fromMail=messages[j].getFrom();
Logger.log("Evaluating message frpm: "+fromMail);
foundAtLocation=archiveCandidates.indexOf(fromMail);
if(foundAtLocation>0){
label=labelCandidate[foundAtLocation];
from=archiveCandidates[foundAtLocation];
Logger.log("Found at:"+foundAtLocation+" Applying label "+label+" for: THREAD ID"+gthreads[i].getId()+" FROM: "+from+" subject: "+messages[j].getSubject());
eveLabel = GmailApp.createLabel(label);
gthreads[i].addLabel(eveLabel);
gthreads[i].moveToArchive();

}
}
}
}
}
[/javascript]

here a screeshot:

Schermafbeelding 2016 02 15 om 21 52 35

screenshot of the trigger/ scheduler…cronjob editor

screeshot_trigger

picketlink implementation notes for websphere

Schermafbeelding 2016 01 28 om 08 44 08


Flow in a nutshell

User acces the application

  • The default deployment descriptor will state that this is a protected resource and needs to be handled by its container
  • The application does its security stuff within the context of websphere security domain, within this domain it is configured to make access to this application only available via a TAI (Trusted Authentication Interceptor)
  • The TAI is configured that authentication errors (which is the case if you access the application the 1st time) should be redirected to the IDP, the TAI makes sure that an authentication (LTPA) cookie is also set:
  • We have configured a SP which an SAML authentication request and sends the request to the IDP
  • The IDP will authenticate and create a SAML token, however due to problems with Websphere accepting the SAML token we had to write a custom Authentication Handler that generates the SAML token according to Websphere standards
  • The IDP redirect to the Assertion Consumer Provider which is basically a webapp which is deployed on Websphere
  • The ACS checks if the SAML token is correct and uses the username from the token to check if the user exists in it’s local LDAP The IDP contains also a X509 certificate which is used as a identifier…this certificate is used by the ACS to check if the certificate is trusted
  • After all ACS checks (X509 check/ SAML token and LDAP check) have been verified, the user is allowed to access the application
  • The ACS uses the Cookie in order to redirect to the appropriate APP, the name of the cookie is: WasSamlSPReqURL  
The Picketlink Authentication HandlerIn order to implement this handler, we have added a module in JBoss with the following config:

<?xml version="1.0" encoding="UTF 8"?> 
<module xmlns="urn:jboss:module:1.1" name=“companyhandler">
<resources> 
<resource root path="idp idp handler 2.1.8.Final.jar"/>
</resources>
<dependencies>
 <module name="org.picketlink"/>
 <module name="org.picketlink.config"/>
<module name="org.picketlink.federation"/>
<module name="org.picketlink.common"/>
<module name="javax.api"/>
 <module name="javax.servlet.api"/>
<module name="org.picketbox"/>
…..
</dependencies>
</module>
 
The main part is in the companySAML2AuthenticationHandler which is an extension of SAML2AuthenticationHandler…this handle overrides the handleRequestType method….basically it does the same…but in order for Websphere to accept this token it needs to get rid of the InResponseTo attribute…

The following code snippet was added:

Document samlResponse = this.getResponse(request); 
Node entries = samlResponse.getFirstChild();
NamedNodeMap nnm = entries.getAttributes();
nnm.removeNamedItem("InResponseTo");
NodeList nList = samlResponse.getElementsByTagName("saml:SubjectConfirmationData"); 
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
Element eElement = (Element) nNode; nnm = eElement.getAttributes();
nnm.removeNamedItem("InResponseTo");
}

The code is called in the IDP by configuring the following in the webapp/WEB INF/picketlink.xml file


<Handlers xmlns="urn:picketlink:identity federation:handler:config:2.1">
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2IssuerTrustHandler" />
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler" />
<Handler class="es.company.jboss_poc.CompanySAML2AuthenticationHandler" />
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.RolesGenerationHandler" />
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureValidationHandler" />
</Handlers>

<! The following was commented out…..is replaced by the es.company.jboss_poc.CompanySAML2AuthenticationHandler

<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler" />

The Websphere TAI only accepts keys from trusted parties…in the IBM documentation it is stated how to configure the keystore… We made ourselves known to Websphere (The TAI is accepting communication with us) by doing the following:

Created our own keystore:

keytool genkey validity 10000 alias HOSTNAME keyalg RSA keysize 1024 dname "CN=HOSTNAME, O=Company, C=ES” keypass PASSWORD keystore identity.jks storepass PASSWORD

Then we added the keystore to Websphere and make the TAI accept certificates from this keystore
Then we needed to extract the X509 certificate for the alias we are going to use: 

keytool export keystore lnxwaslr18.jks rfc alias lnxwaslr18 

This will give you something like this:

MIICAjCCAWugAwIBAgIEMrRLCDANBgkqhkiG9w0BAQsFADA0MQswCQYDVQQGEwJFUzEQMA4GA1UE ChMHQWxsaWFuejETMBEGA1UEAxMKbG54d2FzbHIxODAeFw0xNTEwMDUxNDQ2MTRaFw00MzAyMjAx NDQ2MTRaMDQxCzAJBgNVBAYTAkVTMRAwDgYDVQQKEwdBbGxpYW56MRMwEQYDVQQDEwpsbnh3YXNs cjE4MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqkra4ZxEwExGCb5gerZWEF+dK+iCJag+A z5PIkB/2BP9UP4AomknT93y2czthCDtplzeLGN15UMiURBzdxNtwnMHCr4xku2sFOyuNs7W0yWZ3 9o7Hn1TKvwDfczillKuTF+okP4OllM9mXN5gmietiSrlIwT2kIlzaNAv0MsGHQIDAQABoyEwHzAd BgNVHQ4EFgQUNCK2/WUY51kVN7kyqHU/N4XaH/8wDQYJKoZIhvcNAQELBQADgYEAFUb/efGbZDxq rSw7u6e9j4txbHf+VqtZrVEVkm+r3cNai9vIs7jNzixgaoC6W5kE5x1wtYpkdNjH9EY7SdDFS9EP 7Wt+NI2EdAA3Op50iHjdXiJ5ESHtYNQOFEiTX8+8JglSOAUKacNSdWv0LOm/Ga2GuRe/5LXVfmi5z+eaIIs=

You will need to add the following section in your resources/idp metadata.xml file:

<EntitiesDescriptor Name="urn:mace:shibboleth:testshib:two" ..
<EntityDescriptor entityID="http://lnxwaslr18:8080/idp metadata">
<IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor>
<dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"> <dsig:X509Data>
<dsig:X509Certificate> MIICAjCCAWugAwIBAgIEMrRLCDANBgkqhkiG9w0BAQsFADA0MQswCQYDVQQGEwJFUzEQMA4GA1UE
ChMHQWxsaWFuejETMBEGA1UEAxMKbG54d2FzbHIxODAeFw0xNTEwMDUxNDQ2MTRaFw00MzAyMjAx NDQ2MTRaMDQxCzAJBgNVBAYTAkVTMRAwDgYDVQQKEwdBbGxpYW56MRMwEQYDVQQDEwpsbnh3YXNscjE4MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqkra4ZxEwExGCb5gerZWEF+dK+iCJag+A z5PIkB/2BP9UP4AomknT93y2czthCDtplzeLGN15UMiURBzdxNtwnMHCr4xku2sFOyuNs7W0yWZ3 9o7Hn1TKvwDfczillKuTF+okP4OllM9mXN5gmietiSrlIwT2kIlzaNAv0MsGHQIDAQABoyEwHzAd BgNVHQ4EFgQUNCK2/WUY51kVN7kyqHU/N4XaH/8wDQYJKoZIhvcNAQELBQADgYEAFUb/efGbZDxq rSw7u6e9j4txbHf+VqtZrVEVkm+r3cNai9vIs7jNzixgaoC6W5kE5x1wtYpkdNjH9EY7SdDFS9EP 7Wt+NI2EdAA3Op50iHjdXiJ5ESHtYNQOFEiTX8+8JglSOAUKacNSdWv0LOm/Ga2GuRe/5LXVfmi5 z+eaIIs=
</dsig:X509Certificate> </dsig:X509Data>
</dsig:KeyInfo> </KeyDescriptor>

NB: Only the cursive part

Websphereconfiguration is according to these documents:

http://www.ibm.com/developerworks/websphere/techjournal/1307_lansche/1307_lansche.html https://www 01.ibm.com/support/knowledgecenter/SSD28V_8.5.5/com.ibm.websphere.base.doc/ae/twbs_enablesamlsso.html https://www 01.ibm.com/support/knowledgecenter/SSD28V_8.5.5/com.ibm.websphere.base.doc/ae/rwbs_samltaiproperties.html https://www 01.ibm.com/support/knowledgecenter/SS7JFU_8.5.5/com.ibm.websphere.base.doc/ae/cwbs_samlssosummary.html https://developer.ibm.com/digexp/docs/docs/customization administration/step step guide implement saml 2 0 portal 8 5/

Picketlink configuration


playing with jboss eap and mod_cluster

There are many good articles available on how to configure mod_cluster for jboss eap…some really good ones:

There is even a tool which can help you configure the optimal settings:

http://access.redhat.com/lab/lbconfig

Although there is good literature about this topic, it took me a while to make things work…there are so many pitfalls and possibilities, for eg I spent quite some time configuring wildfly9 and I got this error…MODCLUSTER000042, eventually you get redirected to supported configuration schema’s, you are downloading libraries which seem to be unfindable at first…and before you know it ..half a day is gone.

As I am a lazy bastard…I just want one docker image that does it all, and figure it out later:

  • install 2 jboss instances
  • configure the mod_cluster part on the instances
  • deploy a webapplication on it, which shows you on which server you are
  • put an apache instance in front of it
  • configure mod_cluster to point to one of the jboss instances

I made a docker image available that could save you that half a day, instructions:

  • docker pull cvugrinec/jbosseap63-cluster-withapp:1.4
  • docker run -d -p 8666:80 -p 6666:6666 cvugrinec/jbosseap63-cluster-withapp:1.4
  • if you are on windows or mac and you are using docker-machine, make sure you are port-forwarding the following: 8666 to 8666 and 6666 to 6666
  • then go to your browser and see the mod_cluster config: http://localhost:6666/mod_cluster-manager
  • check the web app with: http://localhost:8666/rws_javaClassicDemo/
  • if you like to tinker with it…just do the docker run -it <pid of docker> bash …and play around in the /opt folder…there you find all the scripts used, config in /etc/httpd/conf.d/jboss.conf, /opt/jboss_instances/instance1/configuration/standalone-ha.xml and /opt/jboss_instances/instance2/configuration/standalone-ha.xml
  • you can find the root password in /README.txt
If you are testing, please note that this is not a simple round robin implementation (you will not be switched from instance with every refresh)
try killing the instance you reside on…refresh and see what happens 

Cheers

rollout jenkins with puppet (ver 4.2)

My notes for creating the puppet module for rolling out jenkins.

create a module template with the build in wizzard

puppet module generate [username]-[name of module]

for e.g.

puppet module generate cvugrinec-jenkins 

After you follow the wizzard (you can (if you like) follow the default values) you will have a module template in the following directory:

/etc/puppetlabs/code/environments/production/modules

your starting point from here will be:

/etc/puppetlabs/code/environments/production/modules/[name of module]/manifest/init.pp

for e.g.

/etc/puppetlabs/code/environments/production/modules/jenkins/manifest/init.pp

Assuming the example: the content of this file will be initially:

#
# a lot of comments
#
class jenkins{
}

In this piece you can add puppet code like:

case $::osfamily { 
'Redhat': {
$msg = "OS on hostname: $hostname is supported, starting install:"
notify{ $msg: }
}
default: {
$msg = " on hostname: $hostname is NOT supported, exiting"
fail("${::osfamily} ${msg}")
}
}

if you like your module to use submodules you can define a subclass.
In the /etc/puppetlabs/code/environments/production/modules/[ module name] /manifest/  directory create a file for e.g. someSuperDuperModule.pp
and define some skeleton code:

class jenkins::someSuperDuperModule{
}

After doing this you need to include this in your init.pp with the following line:

include jenkins::someSuperDuperModule

Ok so far you have a module but this is quite useless …besides the empty code, you like to have this code run on a puppet client….where is all the puppet magic???
One way to realize this is using meta data….
when the puppetclient runs on a pre scheduled time, it will make a call to the puppetmaster the puppetmaster can discriminate based on the meta data from the client what classes need to be executed on the client.

when the client connects to the puppetmaster the main entry point will be:

/etc/puppetlabs/code/environments/production/manifest/site.pp

there you can configure an entry like this:

node “someSuperDuperHostname.local” {
  class { “jenkins" : }

This will execute the jenkins module on the client with hostname: someSuperDuperHostname.local

Next to this you can use hiera for key value lookups…this is very powerfull if you would like to use values in your script.

in the /etc/puppetlabs/code/environments/production/manifest/site.pp you can define this line:

hiera_include('classes')

this will evaluate the /etc/puppetlabs/code/environments/production/hieradata/common.yaml , it should contains something like this:

---
classes:
- jenkins

it will load the jenkins module according to the config of this file /etc/puppetlabs/code/hiera.yaml:


:backends:
  - yaml
:yaml:
  :datadir: /etc/puppetlabs/code/environments/production/hieradata
:hierarchy:
  - "node/%{::fqdn}”
  - common

here you tell that in the /etc/puppetlabs/code/environments/production/hieradata directory there will be a node subdirectory that will contain filenames which will have the name of the hostname of the (puppet) client. The filename will have a .yaml extension. If your puppetclient resides on someSuperDuperHostname.local then the meta data file that will be evaluated for this host will be:
/etc/puppetlabs/code/environments/production/hieradata/node/someSuperDuperHostname.local.yaml

if you have this property configured in your node/someSuperDuperHostname.local.yaml file:

jenkins:
  version: 1.642 

you can test if a value is properly configured with this command:

hiera jenkins.version ::fqdn=someSuperDuperHostname.local

this will return 1.642

So when you are done configuring lets do something and test if the puppetclient loads the desired module:

in the module write some hello world code like this:

class jenkins {
$msg = "HELLO WORLD"
notify{ $msg: } 
}

On your client test your code with the following command:

puppet agent -t

you will see something like this:

NewImage

weak GMS signal

I am living in an area where my reception of my mobile phone sucks….

First I wanted to understand where I can find the strongest GSM signal in my village, so I looked up the “GSM Masten” available in my village

http://www.antenneregister.nl/Html5Viewer_Antenneregister/Index.html?viewer=antenneregister

Then you need to know which one you will need…I have VodaFone…so search the “GSM Mast” with the frequency for Vodafone, you can lookup the frequencies with this wonderful site….it also helps you to understand frequencies and cellular technology in general : http://www.frequentieland.nl/

this page shows a table with frequencies that Dutch cellular providers have:

http://www.frequentieland.nl/gsm/gsm_nl_f.htm

 

Schermafbeelding 2015 08 27 om 23 20 35

 

you can buy a GSM repeater …a GSM signal amplifier on the following sites:

Cell Info on your iphone:
*3001#12345#*
Imei information on your phone
 *#06#


adding multiple java exception lines as 1 message in elasticsearch

There are many ways that lead to Rome, meaning (in this context) that there are many solutions for the question:

“adding multiple java exception lines as 1 message in elastic search”

My solution is adding the following “GROK” filter to my log stash config:

filter {

   multiline {
      pattern => “^[\[\tat] %{GREEDYDATA:DATA}”
      negate => true
      what => “previous”
   }
}

This expressions says that every line starting with (from the beginning of the line (^) ) a tab (\t) and the word at is adding to the previous line…
this the case when you have a stacktrace, for e.g:

Caused by: org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "UK_9QV6YHJQM8IAFTO8QK452GX8H_INDEX_8 ON PUBLIC.MEMBER(EMAIL)"; SQL statement:
insert into Member (email, name, phone_number, id) values (?, ?, ?, ?) [23505-168]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.get(DbException.java:169)
at org.h2.message.DbException.get(DbException.java:146)
at org.h2.index.BaseIndex.getDuplicateKeyException(BaseIndex.java:81)
at org.h2.index.TreeIndex.add(TreeIndex.java:62)
at org.h2.table.RegularTable.addRow(RegularTable.java:121)
at org.h2.command.dml.Insert.insertRows(Insert.java:124)
at org.h2.command.dml.Insert.update(Insert.java:84)
at org.h2.command.CommandContainer.update(CommandContainer.java:75)
at org.h2.command.Command.executeUpdate(Command.java:230)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:156)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:142)
at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeUpdate(WrappedPreparedStatement.java:493)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:186) [hibernate-core-4.2.14.SP1-redhat-1.jar:4.2.14.SP1-redhat-1]

 

Adding LDAP Authentication for JBoss EAP 6

A while ago I scribbled a piece about authentication with ldap on Weblogic, see:

http://datalinks.nl/wordpress/?p=1131

This article does the same for JBoss EAP 6.0. I am using apacheDS as opensource ldap server…
In the article mentioned earlier it shows you how to setup apacheDS (great tool 🙂 and how to create a ldap user…if you have another ldap server that contains your users…you can make an export of a user(s)…and import the ldiff file with the following command:

ldapmodify -h localhost -p 10389 -D “uid=admin,ou=system” -w secret -a -f someExportedLdifFilename.ldif

the command above contains the default values for the apachDS installation…

Configure JBOSS by adding the following sections to your config (default = standalone.xml )

<management>

   <security-realms>

        <security-realm name=”TestRealm”>
           <authentication>
              <ldap connection=”ldap_connection” base-dn=”ou=users,ou=system”>
                 <username-filter attribute=”uid” />
              </ldap>
           </authentication>
        </security-realm>

…..

   </security-realms>

……

     <management-interfaces>
          <native-interface security-realm=”TestRealm”>
             <socket-binding native=”management-native”/>
          </native-interface>
          <http-interface security-realm=”TestRealm”>
             <socket-binding http=”management-http”/>
          </http-interface>
       </management-interfaces>

……

      <outbound-connections>
         <ldap name=”ldap_connection” url=”ldap://127.0.0.1:10389″ search-dn=”uid=admin,ou=system” search-credential=”secret” />
      </outbound-connections>

</management> 

What you just did is defining in the management section a REALM (a collection of users)  and making sure that the interfaces for MGMT communication are using this newly defined security realm.

Setup VPN server and client on MACOS

You like to access your home network from outside your network. For example you are on holiday or at work, via Internet access you like to access your home network to view the WIFI IP camera at your house or just access some files on your server at home.

If you don’t like your network to be accessible for the whole internet you can use the same technology that some companies use; a VPN. A Virtual Private Network (VPN) makes your network available through another (slightly bigger) network…in our case: the internet 🙂

In order to establish this you need to do the following:

  • Setup a VPN server
  • Make your VPN server available through your router or cable modem
  • Test this with your VPN client, you need to configure this as well

I have the following stuff and this article is based on this equipment:

  • IMAC (running Yosemite 10.10.3)
  • MAC AIRPORT EXTREME Router
  • Cable Modem provided by Internet provider (davolink)
  • Iphone 6 (needed for external internet connection) will be needed in order to test the client (my setup (and probably yours too) will not allow external access through your cable modem within the same connection…therefore you need to test your client with another connection)

I am providing this information and I am aware that this could be dangerous for evil-do-ers…but I trust in the goodness of people and that sharing this information would do more good than bad:

Schermafbeelding 2015 07 05 om 23 12 27 Setup VPN MACOS server

Your MAC comes default with all the VPN server stuff installed. There are many VPN servers available from the app store, but if you don’t mind executing some commands within your terminal to configure your built-in VPN server you don’t need to buy stuff. You can configure 2 VPN methods, PPTP or L2TP…you can configure them both, but when connecting you need to choose one of them.

In my network the IMAC with IP 10.0.1.10 (Comp1) will be configured as VPN server: On Comp1, open a terminal and execute the following command:

Create shared key (needed for L2PT) and add to keychain sudo security add-generic-password -a com.apple.ppp.l2tp -s com.apple.net.racoon -T /usr/sbin/racoon -p “SHARED-SECRET-PHRASE” /Library/Keychains/System.keychain Configure the builtin VPND service

  • chown root:wheel /Library/Preferences/SystemConfiguration/com.apple.RemoteAccessServers.plist
  • chmod 644 /Library/Preferences/SystemConfiguration/com.apple.RemoteAccessServers.plist
  • vi /Library/Preferences/SystemConfiguration/com.apple.RemoteAccessServers.plist
  • configure lines 19-20, the OfferedServersAddress
  • configure lines 29-30, the DestAddressRanges
  • create a LaunchD file (will start automatically after reboot)
  • vi /Library/LaunchDaemons/com.apple.ppp.l2tp.plist
  • chown root:wheel /Library/LaunchDaemons/com.apple.ppp.l2tp.plist
  • chmod 644 /Library/LaunchDaemons/com.apple.ppp.l2tp.plist
  • enter the following contents:  
<?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>Label</key>
<string>com.apple.ppp.l2tp</string>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/vpnd</string>
<string>-x</string>
<string>-i</string>
<string>com.apple.ppp.l2tp</string>
</array>
<key>OnDemand</key>
<false/>
</dict>
</plist>
  • Start the service manually: sudo launchctl load -w /Library/LaunchDaemons/com.apple.ppp.l2tp.plist 

I used the following (excellent) blog as source: http://jonsview.com/how-to-setup-os-x-10-9-as-a-l2tp-vpn-server-without-apples-server-app

After running this, when you do an netstat -an, you should be listening to port 1701 in case of L2TP or 1723 in case of PPTP. If you are not then please check if the VPN Daemon is running, otherwise start it with: vpnd

Note: When you have configured your VPN server you can test it directly within your WIFI network (so not yet from outside). At least you know if your vpn server is working… My comp1 , has IP address 10.0.1.10, so when I do the following command: nmap 10.0.1.10 , I should see at least port 1723 listening (for PPTP) or 1701 (for L2TP)

Please note the following ports:

  • UDP port 500 for ISAKMP/ IKE
  • UDP 1701 for L2TP
  • UDP 4500 for IPSEC NAT Traversal (had to wiki this one 🙂
  • TCP 1723 for PPTP

Configure (cable modem) router 

First determine what your external IP address is, This is the address your network will be accessible from, you can find this out by navigating to:

http://whatismyipaddress.com/  or look in the configuration of your router and lookup the value of the WAP IP ADDRESS element

Now configure your cable modem router, in my case I go to the following URL : http://192.168.1.1

There are 2 ways (at least on my cable modem) to make your network accessible…via NAT PORT Forwarding, you will see the following screen:

 

Schermafbeelding 2015 07 05 om 23 51 48

Here you configure your port forwarding per PORT (see overview above, for e.g. port 1723) how to forward it to the next host in your network…in my case 192.168.1.6 (see overview of landscape above).

As I am a lazy person…I configure a DMZ host

Schermafbeelding 2015 07 05 om 23 55 54

this means that all ports will be forwarded to the host defined in the DMZ host section…in my case 192.168.1.6

Configure internal wifi router

As I am the proud owner of an airport extreme, I can configure this device with the airport-configuration utility:

Schermafbeelding 2015 07 06 om 00 03 00

Select the airport extreme (the big fat one on top)…the other devices are just wifi extenders, they are not within the scope of this article

Configuring the airport extreme, go to the NETWORK tab:

Schermafbeelding 2015 07 06 om 00 05 41

Here you configure the ports mentioned earlier in the article, import field is the private IP-address field…this is the IP adress of the VPN server in your network… in my case is this comp1: 10.0.1.10

Schermafbeelding 2015 07 06 om 00 08 55

please note that you see DHCP and NAP on the Router Modus…this is the reason why I have a 192.168.1.x range from my cable modem…this one creates an own internal network within the 10.0.1.x range

Configure and test with VPN client

On your Iphone, go to Configuration —> General —> VPN…configure your external IP adres, your username and password of your IMAC and configure the shared key (in case of choosing the L2TP method)…the IP address I use is: 87.212.242.223…remember test this on an external connection (not within your wifi connection). In the APP store I downloaded FileBrowser…a nice tool to access services and files in your network.

If you have trouble connecting, please also check your firewall rules on your IMAC.