Wednesday, October 14, 2015

How to enable multiple domains in Apache Server using Name-Based VirtualHosts and SSL

Scenario: I have an Apache Server(SSL enabled) and tomcat running on my machine and there is one application (app1) hosted on tomcat which is only accessible from Apache Server. You cannot access it directly from tomcat.
Now you want to access app1 using multiple domains i.e. domain1.waheedtechblog.com annd domain2.waheedtechblog.com should point to the same application which is hosted on tomcat.

(I want to implement different Authentication mechanism based on different domains)
Solution: The above case can be achieved using NameBased VirtualHosts and SSL.
First you need to uncomment following lines form ${apache}/conf/httpd.conf file
  • LoadModule ssl_module modules/mod_ssl.so
  • LoadModule proxy_module modules/mod_proxy.so
  • LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
  • LoadModule rewrite_module modules/mod_rewrite.so
  • LoadModule proxy_http_module modules/mod_proxy_http.so
  • Include conf/extra/httpd-ssl.conf

then goto ${apache}/conf/extra/httpd-ssl.conf file add Virtualhost tag for each domain.

Listen 443
NameVirtualHost *:443

<VirtualHost *:443>

DocumentRoot "c:/Apache2/htdocs"
ServerName domain1.waheedtechblog.com
ServerAdmin admin@example.com
ErrorLog "c:/Apache2/logs/error_domain1.log"
TransferLog "c:/Apache2/logs/access_domain1.log"

SSLEngine on
SSLCertificateFile "C:\Apache2\certificate\domain1.crt"
SSLCertificateKeyFile "C:\Apache2\certificate\domain1.key"

ProxyPass / ajp://sp.domain.com:8009/app1/

BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
</VirtualHost>

<VirtualHost *:443>

DocumentRoot "c:/Apache2/htdocs"
ServerName domain2.waheedtechblog.com
ServerAdmin admin@example.com
ErrorLog "c:/Apache2/logs/error_domain2.log"
TransferLog "c:/Apache2/logs/access_domain2.log"

SSLEngine on
SSLCertificateFile "C:\Apache2\certificate\domain2.crt"
SSLCertificateKeyFile "C:\Apache2\certificate\domain2.key"

ProxyPass / ajp://sp.domain.com:8009/app1/

BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
</VirtualHost>

Points to remember:
  • Add all DNS entry in system hosts file Eg: for windows (Add “127.0.0.1 domain1.waheedtechblog.com” to “C:\Windows\System32\drivers\etc\hosts”)
  • Make sure you are using different certificates and Key for each domain or else it will always point to default VirtualHost i.e. first one that you have defined. Click here on how to generate key and certificate.
  • In proxyPass, always ends with '/' or else you will see redirect issue.

In case of any issue, You can drop your comment in the comment box.

Reference:

https://wiki.apache.org/httpd/NameBasedSSLVHosts

How to generate SSL Key, CSR and Self Signed Certificate using OpenSSL.

I have already discussed how to generate SSL certificate using keytool over here. In this article, I am going to explain how can you achieved the same thing using OpenSSL tool.
The three differnet files that I am going to generate i.e. :
  • waheedtechblog.key
  • waheedtechblog.csr
  • waheedtechblog.crt

Generate Private key : waheedtechblog.key

openssl genrsa -des3 -out waheedtechblog.key 1024



Generate a Certificate Signing Request (CSR)

Using above generated key file, We will now create the CSR file

openssl req -new -key waheedtechblog.key -out waheedtechblog.csr



Generate a Self-Signed SSL Certificate

openssl x509 -req -days 365 -in waheedtechblog.csr -signkey waheedtechblog.key -out waheedtechblog.crt



These file can be used to enable SSL in Apache Server.

Sometime, we need to remove passphrase to run key in Apache Server, if you get such issue while enabling SSL in Apache Server then run following command to remove passphrase :

openssl rsa -in waheedtechblog.key -out waheedtechblog_new.key



Your new file is key without encryption.


Thank you..!!!!




Saturday, October 3, 2015

Configure Shibboleth Idp to achieve Single Sign-on with Zendesk

1. Introduction

Shibboleth is standards-based, open source middleware software which provides web single sign-on across or within organizational boundaries. It allows sites to make informed authorization decisions for individual access of protected online resources in a privacy-preserving manner.
Shibboleth Identity Provider supports the SAML2 specification and is therefore ideal for use with Zendesk. This document will describe the steps required to configure Shibboleth 2.0 Identity Provider to achieve single sign-on with Zendesk.

2. Install Shibboleth IdP

The V2 Shibboleth Identity Provider is a standard Java web application based on the Servlet 2.4 specification and should run for the most part in any compatible servlet container. For this setup, I am going to use Apache Tomcat 7.

  • Install and configure Apache tomcat 7
  • Download the Shibboleth Identity Provider (V2.4.4) software package.
  • Unzip the archive and uncomment <security-constraint>, <login-config> tag from ${shibboleth-identityprovider-2.4.4}\src\main\webapp\WEB-INF\web.xml file.
  • Run install.bat script. The installation directory given during installation will be known as IDP_HOME throughout this document.



  • Register your domain name to 'C:\Windows\System32\drivers\etc\hosts' file eg: '127.0.0.1 idp.waheedtechblog.com'.
  • Add https port in all URLs present in '${IDP_HOME}\metadata\idp-metadata.xml' file i.e change all 'https://idp.waheedtechblog.com/idp/shibboleth' to 'https://idp.waheedtechblog.com:8443/idp/shibboleth'.
  • Skip this step if you have added 'idp.xml' file under '${tomcat}\conf\Catalina\localhost' directory as mentioned in step#1 or else copy '${IDP_HOME}\war\Idp.war' file to '${tomcat}\webapps' directory.
  • Start tomcat and verify it by accessing the URL: https://<HOSTNAME>:<PORT>/idp/profile/Status. If everything is working correctly, It will display a “ok page.


3. Configuring Zendesk


  • Login to your zendesk application and select 'Security' under 'Settings' tab.



  • Add SAML SSO URL as 'https://idp.waheedtechblog.com:8443/idp/profile/SAML2/Redirect/SSO'. You can find this URL in your '${IDP_HOME}\metadata\idp-metadata.xml' file as HTTP-Redirect URL.
  • Certificate fingerprint: Double click on '${IDP_HOME}\credentials\idp.crt' file and copy 'thumbprint' value from 'Details' tab. Don't forget to remove the spaces.
  • Remote Logout URL and IP Ranges are optional. Save it.

4. Configuring Shibboleth Idp

To support SSO, We need to modify many files of IdP.

4.1 Enable logging

Before configuring anything, we should enable LOG at level DEBUG so that we can easily find out the issue. The Identity Provider uses the Logback logging system and logging configuration is located at $IDP_HOME/conf/logging.xml.

Change logger and root level as DEBUG

<logger name="edu.internet2.middleware.shibboleth" level="DEBUG”>
<root level="DEBUG">
<appender-ref ref="IDP_PROCESS"/>
</root>


The file changes will be reflected with in 10 minutes without restarting the IdP and check idp-process.log file for any issue.


4.2 Configure Username/Password Authentication

Authentication handler supports authenticating users with a username (netid) and password.
Uncomment username/password login handler in ${IDP_HOME}/conf/handler.xml file

<ph:LoginHandler xsi:type="ph:UsernamePassword"
jaasConfigurationLocation="file://C:\idpV2.4.4/conf/login.config">
<ph:AuthenticationMethod>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</ph:AuthenticationMethod>
</ph:LoginHandler>


and Comment RemoteUser login handler


<!-- <ph:LoginHandler xsi:type="ph:RemoteUser">
<ph:AuthenticationMethod>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</ph:AuthenticationMethod>
</ph:LoginHandler> -->





Note: Sometimes Idp is not able to find out the login.conf file as mentioned in Username\password login handler. In such cases add one extra '/' in the file path i.e.                                 jaasConfigurationLocation="file:///C:\idpV2.4.4\conf\login.config" 

4.3. Add LDAP Login Module Specification

Add Ldap configuration for Authentication to ${IDP_HOME}/conf/login.conf file.

Uncomment and modified LdapLoginModule as per your local environment

edu.vt.middleware.ldap.jaas.LdapLoginModule required

ldapUrl="ldap://localhost:389"

base="dc=altisource,dc=com"
serviceUser="cn=Directory Manager"
serviceCredential="root123"
ssl="false"
subtreeSearch="true"
userFilter="uid={0}";

Where

ldapUrl: url of the ldap where it is running
base: location where you have actually stored username/password (Base DN)
serviceUser: Administrative users using which you connect to Ldap
serviceCredential: Password of the ldap


This is how my Ldap Connection looks like



4.4 Add Zendesk metadata to IdP

The Shibboleth IdP must know some basic information about the Zendesk relying party, which is defined in SAML metadata. Create new IDP_HOME/metadata/zendesk-metadata.xml file with the following contents. There is much more information that could be added here, but this is the minimum required to get things working and replace YOURDOMAIN with the domain you have setup in Zendesk.

<?xml version="1.0" encoding="UTF-8"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
validUntil="2015-10-03T12:10:16Z"
cacheDuration="PT1444306216S"
entityID="YOURDOMAIN.zendesk.com">
<md:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://YOURDOMAIN.zendesk.com/access/saml"
index="1" />
</md:SPSSODescriptor>
</md:EntityDescriptor>



4.5 Configure Relying Party (relying-party.xml)


  • Instruct Shibboleth how to behave when talking to Zendesk by defining a new RelyingParty element in ${IDP_HOME}/conf/relying-party.xml. The following snippet should be added just after the DefaultRelyingParty element. Change the id and provider value as per your configuration.

<!-- relying party for zendesk -->
<rp:RelyingParty id="https://YOURDOMAIN.zendesk.com"
provider="https://idp.waheedtechblogsso.com:8443/idp/shibboleth"
defaultSigningCredentialRef="IdPCredential">
<rp:ProfileConfiguration xsi:type="saml:SAML2SSOProfile" encryptAssertions="never" encryptNameIds="never" signResponses="never" />
</rp:RelyingParty>



  • Add the following snippet to configure new metadata (zendesk-metadata.xml) file you have created earlier.

<!-- zendesk Metadata -->
<metadata:MetadataProvider id="IdPSP" xsi:type="metadata:FilesystemMetadataProvider"
metadataFile="c:\\idpV2.4.4\\metadata\\zendesk-metadata.xml" >
</metadata:MetadataProvider> 





  • Change encryptAssertions="conditional" to encryptAssertions="never " in 'SAML2SSOProfile' 

<rp:ProfileConfiguration xsi:type="saml:SAML2SSOProfile" includeAttributeStatement="true"
assertionLifetime="PT5M" assertionProxyCount="0"
signResponses="never" signAssertions="always"
encryptAssertions="never" encryptNameIds="never"
includeConditionsNotBefore="true"/>





4.6 Configure Attribute Resolver (attribute-resolver.xml)

Zendesk expects the email of the user logging in to be passed as the SAML Name Identifier. Shibboleth’s attribute resolver must be configured to make this data available by modifying ${IDP_HOME}/conf/attribute-resolver.xml.

Uncomment and modify Ldap data connector


<resolver:DataConnector id="openDJ" xsi:type="dc:LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
ldapURL="ldap://localhost:389"
baseDN="dc=domain, dc=com"
principal="cn=Directory Manager"
principalCredential="root123">
<dc:FilterTemplate>
<![CDATA[
(uid=$requestContext.principalName)
]]>
</dc:FilterTemplate>
<ReturnAttributes>mail cn</ReturnAttributes>
<LDAPProperty name="java.naming.ldap.attributes.binary" value="objectSid"/>
<LDAPProperty name="java.naming.referral" value="follow"/>
</resolver:DataConnector>




and then add the following attribute definition that was used to authenticate to the IdP.

<resolver:AttributeDefinition xsi:type="Simple" xmlns="urn:mace:shibboleth:2.0:resolver:ad" id="userEmailId" sourceAttributeID="mail">
<resolver:Dependency ref="openDJ" />
<resolver:AttributeEncoder xsi:type="enc:SAML2StringNameID" xmlns="urn:mace:shibboleth:2.0:attribute:encoder" nameFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" />
</resolver:AttributeDefinition>


<resolver:AttributeDefinition xsi:type="Simple" xmlns="urn:mace:shibboleth:2.0:resolver:ad" id="common_name" sourceAttributeID="cn">
<resolver:Dependency ref="openDJ" />
<resolver:AttributeEncoder xsi:type="enc:SAML2StringNameID" xmlns="urn:mace:shibboleth:2.0:attribute:encoder" name="common_name" />
</resolver:AttributeDefinition>





4.7 Configure Attribute Filter (attribute-filter.xml )

Finally, configure the Shibboleth attribute filtering engine to release the principal attribute (encoded as a NameID) to Zendesk. Add the following XML snippet to ${IDP_HOME}/conf/attribute-filter.xml alongside the existing policy elements.

<afp:AttributeFilterPolicy id="releaseTransientIdToAnyone">
<afp:PolicyRequirementRule xsi:type="basic:ANY"/>
<afp:AttributeRule attributeID="userEmailId">
<afp:PermitValueRule xsi:type="basic:ANY"/>
</afp:AttributeRule>

<afp:AttributeRule attributeID="common_name">
<afp:PermitValueRule xsi:type="basic:ANY"/>
</afp:AttributeRule>
</afp:AttributeFilterPolicy>



5. Verification

If everything goes well, our Shibboleth Idp should authenticate users to zendesk application.
Let's access zendesk domain: https://waheedtechblogsso.zendesk.com


It will redirect to Shibboleth Idp page for user credential




Once you entered the credential, it will redirect back to zendesk home page. (Just make sure you have the same credential in LDAP that you have used in zendesk to register it.)





Congratulation ...!!!