Showing posts with label web security. Show all posts
Showing posts with label web security. Show all posts

Aug 29, 2017

Generate a SANs certificate

We are going to use openssl to generate a certificate with subject alternative names. When we use SANs in a certificate we can use the same certificate to front several websites with different domain names.

First we need to generate a private key. Since we are going to use this in a web server like Nginx or apache I'm not going to encrypt the private key with a passphrase.


openssl genrsa -out thilina.org.key 2048


Then we need to have a configurations file to add those alternative names into the certificate signing request (CSR).

sans.conf

[ req ]
default_bits       = 2048
distinguished_name = req_distinguished_name
req_extensions     = req_ext

[ req_distinguished_name ]
countryName         = Country Name (2 letter code)
stateOrProvinceName = State or Province Name (full name)
localityName        = Locality Name (eg, city)
organizationName    = Organization Name (eg, company)
commonName          = Common Name (e.g. server FQDN or YOUR name)

[ req_ext ]
subjectAltName = @alt_names

[alt_names]
DNS.1=thilina.org
DNS.2=api.thilina.org
DNS.3=gateway.thilina.org


Now I'm going to generate the CSR in a single command.


openssl req -new -key thilina.org.key -sha256 -nodes -out thilina.org.csr \
  -subj "/C=LK/ST=Colombo/L=Colombo/O=Thilina Piyasundara/OU=Home/CN=thilina.org" \
  -config san.conf


Print and verify the CSR


openssl req -in thilina.org.csr -text -noout



Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = LK, ST = Colombo, L = Colombo, O = Thilina Piyasundara, OU = Home, CN = thilina.org
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:d0:13:91:5d:62:7c:4f:57:6d:4c:79:85:59:d8:
                    c5:ae:50:41:cc:db:fe:b4:75:fc:c1:73:e7:a7:ac:
                    89:36:3b:26:08:0f:33:b0:96:5c:29:a1:ee:9a:14:
                    13:4b:5b:43:74:74:a2:fd:97:2b:2b:bd:2a:b8:e6:
                    22:d2:01:15:f3:7f:e9:d8:c9:d4:65:04:5a:ef:f0:
                    03:41:63:56:39:eb:5f:e5:90:de:33:b7:bb:60:0e:
                    e3:70:79:60:8f:cb:a9:71:3b:e3:0a:b1:17:47:aa:
                    41:08:b5:44:5e:1a:a1:fa:a2:ce:ed:18:c5:a3:b0:
                    6f:0f:57:ca:ae:28:7f:91:49:14:6b:94:4c:3c:33:
                    fb:27:ed:77:37:a7:d6:54:4e:a7:6e:bc:c9:a2:a1:
                    b5:f2:f0:aa:76:64:04:83:96:92:03:36:4c:3e:14:
                    0e:97:a6:79:9e:23:c1:2a:c4:7a:3d:6e:f3:1c:40:
                    e3:d1:61:f2:56:51:8f:0f:04:76:62:ea:b0:1f:94:
                    e8:a8:8b:54:d6:08:5a:79:a6:a4:a0:00:fb:5f:c3:
                    d5:d4:50:ea:15:12:ea:9b:10:cc:9a:d9:32:6e:48:
                    93:30:4b:e7:2e:fe:a9:a0:31:16:61:24:3f:29:54:
                    2a:25:da:d2:b3:6a:d9:d5:a9:51:ee:d3:bb:b9:83:
                    86:59
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Subject Alternative Name:
                DNS:thilina.org, DNS:api.thilina.org, DNS:gateway.thilina.org
    Signature Algorithm: sha256WithRSAEncryption
         96:44:43:98:60:76:49:ad:8b:01:65:20:f1:ca:4a:47:84:67:
         dc:77:f0:2e:bb:30:68:8b:2f:79:c4:4c:10:91:ec:70:fe:73:
         9c:3e:f4:69:18:8c:34:f6:85:05:26:b1:2a:35:38:f5:93:59:
         c2:a4:07:83:73:79:88:9b:ff:17:99:66:34:58:21:bc:de:8e:
         65:b9:50:bb:18:52:53:9b:ed:a3:4e:c7:55:73:2e:42:47:dc:
         94:4d:fb:cc:ba:b1:7a:57:a6:f9:fa:27:a2:54:aa:cd:f6:79:
         3d:b7:0a:82:a3:18:41:ec:f5:db:cc:05:6a:43:64:d7:4a:00:
         fe:a3:89:f9:25:f3:79:55:f9:79:3a:b2:96:5e:9d:67:f5:c7:
         e4:ab:fc:da:cb:df:f5:76:36:44:fe:d2:87:3a:d7:a2:a9:2e:
         fc:7f:ba:a6:12:44:70:e0:c4:42:57:01:1e:51:0a:d4:2e:33:
         e2:63:20:c2:9a:07:1b:78:e8:fb:42:b5:e5:85:00:b1:2c:25:
         d8:ad:43:af:6a:01:09:59:7e:d0:af:dd:72:f3:93:18:30:38:
         c2:b0:6c:8e:88:79:4e:16:fe:e3:87:46:c2:eb:f3:2e:2b:aa:
         a7:a9:76:1d:fd:8b:d9:d9:1c:a3:1c:21:db:af:b0:0b:7e:15:
         37:37:0f:25



Validate the key, csr and certificates are matching.

openssl rsa -noout -modulus -in domain.key | openssl md5
openssl x509 -noout -modulus -in domain.crt | openssl md5
openssl req -noout -modulus -in domain.csr | openssl md5


Apr 2, 2016

Add Let's Encrypt free SSL certificates to WSO2 API Cloud

Let's encrypt is a free and open certificate authority runs for the public benefit. This service is provided by the Internet Security Research Group and there are lots of companies working with them to make the Internet secure. People who have a domain name can get free SSL certificate for their websites using this service for three months. I they need to use for more than that three months we need to renew the certificate and its also for free. But the best thing is that this certificate is accepted by most of the new web browsers and systems by default. So you don't need to add CA certs to you browsers any more.

In this article I will explain how we can use that service to get a free SSL certificate and add that to WSO2 API Cloud. So that you can have your own API store like;

https://store.thilina.piyasundara.org

In order to do that you need to have following things in hand.
  • Domain name.
  • Rights to add/delete/modify DNS A records and CNAMEs.
  • Publicly accessible webserver with root access or a home router with port forwarding capabilities. 

Step 1

If you have a publicly accessible webserver you can skip this step.If you don't have a publicly accessible webserver you can make your home PC/Laptop a temporary webserver if you can do port forwarding/NATing in you home router. I will show how I did that with my ADSL router. You can get help on port forwarding information by referring to this website http://portforward.com.

a. Add a port forwarding rule in your home router.

Get your local (laptop) IP (by running ifconfig/ip addr) and put that as the backend server in your router for. Set the WAN port as 80 and LAN port as 80.


After adding the rule it will be like this.

b. Start a webserver in your laptop. We can use the simple Python server for this. Make sure to check the IPTable rules/Firewall rules.

mkdir /tmp/www
cd /tmp/www/
echo 'This is my home PC :)' > index.html
sudo python3 -m http.server 80

c. Get the public IP of your router. Go to this link : http://checkip.dyndns.org it will give the public IP address. This IP is changing time-to-time so no worries.


d. Try to access that IP from a browser.
If it is giving the expected output you have a publicly accessible webserver.


Step 2

Now we need to update a DNS entry. My expectation is to have a single SSL certificate for both domains 'store.thilina.piyasundara.org' and 'api.thilina.piyasundara.org'.

a. Go to your DNS provides console and add an A record for both domain names to point to the public IP of your webserver (or the IP that we got from the previous step).


b. Try to access both via a browser and if its giving the expected out put you can proceed to the next step.


Step 3

I'm follow the instruction in the 'let's encrypt' guide. As I'm using the python server I need to use the 'certonly' option when running the command to generate the certs.

a. Get the git clone of the letsencrypt project.

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt

b. Run cert generation command. (this requires root/sudo access)

./letsencrypt-auto certonly --webroot -w /tmp/www/ -d store.thilina.piyasundara.org -d api.thilina.piyasundara.org

If this succeed you can find the SSL keys and certs in '/etc/letsencrypt/live/store.thilina.piyasundara.org' location.

Step 4

Check the content of the certs. (Be root before you try to 'ls' that directory)

openssl x509 -in cert.pem -text -noout

Step 5

Create an API in WSO2 API Cloud if you don't have one. Else start on adding a custom domain to your tenant.

a. Remove both A records and add CNAME records to those two domains. Both should point to the domain 'customdns.api.cloud.wso2.com'.


b. Now click on the 'Configure' option in the top options bar and select the 'Custom URL' option.


c. Make ready you SSL certs. Copy 'cert.pem', 'chain.pem' and 'privkey.pem' to you home directory.

d. Modify API store domain. Click on the modify button, add the domain name click on verify. It will take few seconds. If that succeed you have correctly configured the CNAME to point to WSO2 cloud.

e. Add cert files to the API Cloud. The order should be the certificate (cert.pem), private key (privatekey.pem) and the CAs chain file (chain.pem). Again it will take sometime to verify uploaded details.


f. Update the gateway domain same as the previous.

Now if you go the API Store it will show something like this.



g. Same way you can use the gateway domain when you need to invoke APIs.

curl -X GET --header 'Accept: application/json' --header 'Authorization: Bearer ' 'https://gateway.api.cloud.wso2.com:8243/t/thilina/gituser/1.0.0/thilinapiy'

Now you don't need '-k' option. If not make sure you operating system (CA list) is up to date.

Step 6

Make sure to remove port forwarding in you home router if you use that and any changes that you make while obtaining the SSL certificates.

Jan 24, 2013

Clean URL using .htaccess


These days most websites use databases or a content management system (CMS). Some of those web sites or systems have nice URLs like;

 example.com/your-random-page

But some systems have URLs like;

 example.com/index.php?q=your-random-page

Both URLs give the same output, but the clean URL is good for search engine optimizations and easy to remember.

If you want to retrieve data from a database according to a input given in the URL you need to use a GET request. So how a clean URL works ?

In a clean URL scenario, web server need to do a redirection. Server will redirect the clean URL request to a not clean URL. Then from the not clean URL, index page will generates the relevant content. But this redirection will not be visible to the user.

 example.com/your-random-page => example.com/index.php?q=your-random-page

So if you change the URL into something else, it will change the value of the parameter in to that like;

 example.com/something-else => example.com/index.php?q=something-else

Then the index page will generate the relevant content according to that value.

TO do these things you need to enable some web server options. First you need to enable '.htaccess'. Then you need to enable 'mode rewrite' mode. '.htaccess' is a part of a server settings file. you can specifically set web server settings via this file and if you do something wrong, that can cause a damage to the webserver too.

Place a '.htaccess' file in the root of you website and add these lines to it.

RewriteEngine On
RewriteRule ^([a-zA-Z0-9]+)$ index.php?q=$1
RewriteRule ^([a-zA-Z0-9]+)/$ index.php?q=$1

Jan 5, 2013

Open a Linux firewall port - IPTables

IPTables is the default firewall in any unix/linux system. If we host a service such as FTP or web server, we need to open some ports in order to use that service from remote hosts. For that we need to edit the configurations in this firewall.

First we can check the status of IPTables by running this command;

service iptables status

By default most systems open the ssh port 22. Now we need to get the running configurations to edit it. To do that;

iptables-save > /tmp/iptables

This command will dump the running iptables configurations in to a file and it will be like this.

# Generated by iptables-save v1.4.7 on ...
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [39:2878]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A INPUT -p icmp -j ACCEPT 
-A INPUT -i lo -j ACCEPT 
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT 
-A INPUT -j REJECT --reject-with icmp-host-prohibited 
-A FORWARD -j REJECT --reject-with icmp-host-prohibited 
COMMIT
# Completed on ...

Assume that we need to run a web server on this host. Web servers usually runs on port 80. Therefore, we need to allow port 80. To allow that we can add a line similar to the ssh rule.

-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT 
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT 
-A INPUT -j REJECT --reject-with icmp-host-prohibited 

Then you need to feed this configurations to the iptables. To do that;

iptables-restore < /tmp/iptables

Now if you run the 'service iptables status' command, you can see port 80 is also allowed in it. But if you restart the service (service iptables restart) or reboot the machine, those changes will be not there. That's because it use a default configuration file on the service initialization. This default file is different from system to system. In CentOS systems that file is locates in '/etc/sysconfig/iptables'. After all the things are complete, you can save the running iptables configurations on that file it self.

But it is better if you use an alternative method like 'cron job' to run modify this iptables configurations. To do that you need to add a cron job as root by;

crontab -e

and add;

@reboot /sbin/iptables-restore < /root/myiptables

 The modified iptables rule set must be located on that location.

Note: In few Linux distributions there is a another firewall called 'SELinux'. If you have an issue even after changing those settings in IPTables, it is better to check SELinux settings too.

Jan 4, 2013

Deny Youtube in office hours using Squid proxy

We can use Squid-cache as a internet access controlling system. In this post I will show you how to configure squid-cache to do access controlling on youtube.com website.

You need to edit the '/etc/squid/squid.conf' file to these changes.

First we need to defined our local network (eg : 192.168.2.0/24 ). To do that we can edit the 'acl localnet src * ' line in the config file to;

acl localnet src 192.168.2.0/24

Then we assume that we need to block youtube access within working hours to all uses in the network. Therefore, we need to set the working hours in the configurations file. This configuration should come soon after defining 'Safe_ports'.

acl officehours time M T W H F 8:00-17:00

Now you can give the host name of the host machine by;

visible_hostname proxy.domain.com

If anyone need to access youtube within office hours we need to have a option for that. For an example, we can set a youtbe allowed IP range and/or some individual IP addressed like this.

acl allowyoutube src 192.168.2.21-192.168.2.40
acl allowyoutube src 192.168.2.75
acl allowyoutube src 192.168.2.65

Now we can block youtube to all users except special users by setting;

acl youtube dstdomain .youtube.com
http_access deny CONNECT youtube !allowyoutube officehours
http_access deny youtube !allowyoutube officehours

# deny access to not safe and non-ssl ports
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports

# allow only local network
http_access allow localnet
http_access deny all

Then restart the squid service  and see the logs on ' /var/log/squid/ ' for more information.