Configuring NAT on Juniper J-series

July 17th, 2008 Remco Bressers 6 comments

In the past, i configured a lot of nifty things on Juniper M-series routers like BGP, OSPF and all sorts of routing stuff. Back to basics (NAT) would have to be a piece of cake :-) .

But…

Configuring NAT on a J-series Juniper box is pretty well documented in the Juniper documentation. I mean.. VERY well documented in a way nobody seems to get the whole point about NAT’ting on the box.

The most straightforward NAT configuration is never being discussed anywhere in the documentation and that makes it pretty hard to get it to work. After some braincracks, i finally managed to get it to work in a way i want it.

The usual CPE setup applies here, so we have one single public IP address on the outside and an RFC1918 192.168.1.0/24 subnet on the inside interface. Our default gateway resides at 217.1.10.254. Our mailserver is at 192.168.1.254, doing only SMTP.

NAT the easy way

“NAT the easy way”

Alright, now we know how to setup the network, let’s configure the J-box. Forget the J-web interface as we’re not going to use it. JunOS CLI it is.
Please note that i’m not running JunOS enhanced services in this example. With ES it should be a little more straightforward and easier to configure, but i just wanted it to run on the plain vanilla JunOS 9.1
Log in to the box, and start configuring the default stuff:
remco@router> configure
remco@router# set system host-name myrouter
remco@router# set system domain-name remcobressers.nl
remco@router# set root-authentication plain-text-password

    Enter your password here for root access.

remco@router# set domain-search remcobressers.nl
remco@router# set time-zone Europe/Amsterdam
remco@router# set location country-code nl
remco@router# set system name-server 217.1.10.10 217.1.10.11
remco@router# set system login user remco uid 2000 class super-user authentication plain-text-password

    Enter your user password to enter the CLI.

remco@router# set system services ssh

Alright. We’re all set. Now let’s configure the interfaces. Let’s say ge-0/0/0 is our outside WAN interface and ge-0/0/1 is the inside LAN interface.

remco@router# edit interfaces ge-0/0/0
[edit interfaces ge-0/0/0]
remco@router# set description "WAN"
remco@router# set unit 0 family inet address 217.1.10.1/24

remco@router# top
[edit]
remco@router# edit interfaces ge-0/0/1
[edit interfaces ge-0/0/1]
remco@router# set description "LAN"
remco@router# set unit 0 family inet address 192.168.1.1/24
remco@router# top
[edit]
remco@router# set routing-options static route 0.0.0.0/0 next-hop 217.1.10.1

Ok. Our basic setup is completed. Let’s configure NAT. We have an internal server at 192.168.1.254 which does SMTP, so we need to configure 2 things:

  • NAT from LAN to the WAN (overload)
  • NAT port forwarding from WAN to 192.168.1.254 SMTP on the LAN

Shouldn’t be to difficult.

remco@router# edit services service-set wan-service-set
[edit services service-set wan-service-set]
remco@router# set nat-rules nat-outgoing
remco@router# set nat-rules nat-incoming
remco@router# set interface-service service-interface sp-0/0/0.0
remco@router# up
[edit services]
remco@router# edit nat
[edit services nat]
remco@router# set pool nat-pool address-range low 217.1.10.1 high 217.1.10.1
remco@router# set pool nat-pool port automatic
remco@router# edit rule nat-outgoing
[edit services nat rule nat-outgoing]
remco@router# set match-direction output
remco@router# set term 1 then translated source-pool nat-pool
remco@router# set term 1 then translated translation-type source dynamic
remco@router# up
[edit services nat]
remco@router# edit rule nat-incoming
[edit services nat rule nat-incoming]
remco@router# set match-direction input
remco@router# set term smtp from destination-address 217.1.10.1/32
remco@router# set term smtp from applications junos-smtp
remco@router# set term smtp then translated destination-prefix 192.168.1.254/32
remco@router# set term smtp then translated translation-type destination static
remco@router# set term other from destination-address 217.1.10.1/32
remco@router# set term other then no-translation

Alright. This looks like a little confusing. It all comes down to the following.

  1. Create a service-set named “wan-service-set”, which holds our nat rules “nat-outgoing” and “nat-incoming”. Services needs a virtual services interface. In this case, the default is sp-0/0/0.0.
  2. In the NAT configuration, we create a pool, which holds one single public IP address (217.1.10.1). The ports are dynamically assigned.
  3. Our outgoing NAT rule is used to translate our internal traffic to the Internet on the public address. Our source pool is the pool we just created.
  4. Our incoming NAT rule is used to translate incoming SMTP traffic to our internal SMTP server at 192.168.1.254.
  5. We use the application “helper” junos-smtp instead of creating our own application. The result is the same.
  6. Other incoming traffic won’t be translated (this is important to include).

We now need to configure the service-set “wan-service-set” to the interface we do the translation on, which is the outside interface ge-0/0/0.

remco@router# top
[edit]
remco@router# edit interfaces ge-0/0/0 unit 0 family inet
[edit interfaces ge-0/0/0 unit 0 family inet]
remco@router# set service input service-set wan-service-set
remco@router# set service output service-set wan-service-set

Alright, that’s about it. You can commit the configuration now with the “commit” command.
Your configuration will now look like this :

remco@router# top
[edit]
remco@router# show

## Last changed: 2008-07-17 21:13:49 CEST
version 9.1R1.8;
system {
    host-name myrouter;
    domain-name remcobressers.nl;
    domain-search remcobressers.nl;
    time-zone Europe/Amsterdam;
    location country-code nl;
    root-authentication {
        encrypted-password "**************"; ## SECRET-DATA
    }
    name-server {
        217.1.10.10;
        217.1.10.11;
    }
    login {
        user remco {
            uid 2000;
            class super-user;
            authentication {
                encrypted-password "***********"; ## SECRET-DATA
            }
        }
    }
    services {
        ssh {
        }
    }
}
interfaces {
    ge-0/0/0 {
        description "WAN";
        unit 0 {
            family inet {
                service {
                    input {
                        service-set wan-service-set;
                    }
                    output {
                        service-set wan-service-set;
                    }
                }
                address 217.1.10.1/24;
            }
        }
    }
    sp-0/0/0 {
        unit 0 {
            family inet;
        }
    }
    ge-0/0/1 {
        description "LAN";
        unit 0 {
            family inet {
                address 192.168.1.1/24;
            }
        }
    }
}
routing-options {
    static {
        route 0.0.0.0/0 next-hop 217.1.10.254;
    }
}
services {
    service-set wan-service-set {
        nat-rules nat-outgoing;
        nat-rules nat-incoming;
        interface-service {
            service-interface sp-0/0/0.0;
        }
    }
    nat {
        pool nat-pool {
            address-range low 217.1.10.1 high 217.1.10.1;
            port automatic;
        }
        rule nat-outgoing {
            match-direction output;
            term 1 {
                then {
                    translated {
                        source-pool nat-pool;
                        translation-type {
                            source dynamic;
                        }
                    }
                }
            }
        }
        rule nat-incoming {
            match-direction input;
            term smtp {
                from {
                    destination-address {
                        217.1.10.1/32;
                    }
                    applications junos-smtp;
                }
                then {
                    translated {
                        destination-prefix 192.168.1.254/32;
                        translation-type {
                            destination static;
                        }
                    }
                }
            }
            term other {
                from {
                    destination-address {
                        217.1.10.1/32;
                    }
                }
                then {
                    no-translation;
                }
            }
        }
    }
}
Categories: Networking Tags:

Running an iSCSI SAN on CentOS 5

July 14th, 2008 Remco Bressers 3 comments

Running iSCSI target on a Fedora system is as easy as “yum install iscsitarget” and configure the thing. Unfortunatly, on CentOS, the iSCSI Enterprise Target (IET) daemon is not in the default Yum repositories, because CentOS usually uses TGT (Linux SCSI Target Framework).

Ok, i could dive into using TGT on a CentOS box, but that’s not what i wanted to use on a corporate SAN. So, let’s find it out the hard way and build from source.

The iSCSI Target system

First, some prerequisites :

# yum install kernel-devel openssl-devel gcc rpm-build

Download the latest IET from the Sourceforge repo and put the tgz in /usr/src

# cd /usr/src
# tar xvf iscsitarget-0.4.15.tar.gz
# cd iscsitarget-0.4.15
# make
# make install

Alright. IETD is installed and ready to use. The iscsi-target init.d script is installed and will be started at boot-time. Nice! One bad thing is, that every time you install a new kernel, you need to recompile ietd. Write this down on your forehead or somewhere you will look at every single day :-)

Configuring ietd is a piece of cake if the documentation would be easy findable, but it isn’t (or wasn’t).
First, lets decide who can connect to the IET daemon :

# vi /etc/initiators.allow
iqn.2008-07.my-sanhead:mydiskname 192.168.1.0/24

Yep, quite a strange string. It’s called an IQN (iscsi qualified name) and i use this naming convention:
iqn.<year>-<month>.<hostname>:<LVM diskname>
The IQN is an identifier for your iSCSI target. A target can consist of multiple disks and/or lun’s. The iSCSI initiator uses the IQN to connect to these disks/lun’s. The subnet 192.168.1.0/24 is allowed to use this iSCSI target.

Next, we’ll create the initiators.deny file, which is pretty straightforward :

 # vi /etc/initiators.deny
ALL:ALL

Time to create the IQN in the ietd configuration file.

# vi /etc/ietd.conf
Target iqn.2008-07.my-sanhead:mydiskname
        IncomingUser username 12345
        OutgoingUser username 123456789012
        Lun 0 Path=/dev/SAN/diskname,Type=fileio,IOMode=wb
        Alias iSCSI for diskname
        ImmediateData Yes
        MaxConnections 1
        InitialR2T Yes

I use the following conventions, as defined in the RFC :

For IncomingUser: Password always 5 characters
For OutgoingUser: Password always 12 characters

I use LVM as a disk backend. The disk can also be /dev/sdb or whatsoever.


The iSCSI Initiator

For the initiator, we’re also going to use a CentOS system, as this is my OS of choice. In Ubuntu/Debian/Fedora/Whatever-linux-u-may-have there usually is an open-iscsi in the repository. If not, you can always compile it from source at http://www.open-iscsi.org.

Let’s install the prerequisites :

# yum install iscsi-initiator-utils
# yum install open-iscsi

Next, define the initiatorname. This is in the exact same form as the targetname, but it should not be the same. This initiatorname is the name (in IQN) of your computer.

# vi /etc/iscsi/initiatorname.iscsi

InitiatorName=iqn.2008-07.mydesktoppc:someuniquename

Next, we’re going to configure the authentication and some specials in the iscsid config.

# vi /etc/iscsi/iscsid.conf

node.startup = automatic
node.session.auth.authmethod = CHAP
node.session.auth.username = username
node.session.auth.password = 12345
node.session.auth.username_in = username
node.session.auth.password_in = 123456789012
node.session.timeo.replacement_timeout = 120
node.conn[0].timeo.login_timeout = 15
node.conn[0].timeo.logout_timeout = 15
node.conn[0].timeo.noop_out_interval = 10
node.conn[0].timeo.noop_out_timeout = 15
node.session.initial_login_retry_max = 10
node.session.cmds_max = 128
node.session.queue_depth = 32
node.session.iscsi.InitialR2T = No
node.session.iscsi.ImmediateData = Yes
node.session.iscsi.FirstBurstLength = 262144
node.session.iscsi.MaxBurstLength = 16776192
node.conn[0].iscsi.MaxRecvDataSegmentLength = 131072
discovery.sendtargets.iscsi.MaxRecvDataSegmentLength = 32768
node.session.iscsi.FastAbort = No

For more information about these setting, please refer to the open-iscsi page.
Next up, start the thing :

# service iscsi start

Bingo! You just started the iSCSI daemon (all cheer). Now, we’re going to discover our targets on the target iSCSI host. I assume 192.168.1.1 is the target host in this example.

# iscsiadm -m discovery -t st -p 192.168.1.1
192.168.1.1:3260,1 iqn.2008-7.my-sanhead:mydiskname

As you can see, it found the target we created before. Now, let’s login to it:

# iscsiadm -m node -p 192.168.1.1  -T iqn.2008-7.my-sanhead:mydiskname --login

Et voila! If you do a ‘dmesg’ on your box, you will find a new disk inserted (/dev/sdc or whatever).

Have fun!

Categories: SysAdmin Tags:

Create your own Mozilla Weave server

July 10th, 2008 Remco Bressers 35 comments

updated: Fri Jul 18 : Added SSL VirtualHost configuration for a secure environment.
updated: Fri Oct 17 : Just increased version numbers to Weave 0.2.7.

Mozilla Weave is a pretty neat extension to the pretty neat Firefox 3 browser. This extension can synchronize your bookmarks, cookie data, saved passwords, history and form data to a WebDAV server maintained and hosted by Mozilla.

Since Weave is only at version 0.2.7 (at the time of writing), the project is heavily in development and the WebDAV server is dead slow and offline from time to time. The nice thing about free mozilla stuff is that almost everything is possible, even building your own WebDAV server.

We don’t just want a WebDAV server, but we want the exact same setup as Weave uses, including tight user authentication and security on the storage. The only thing that really bothers me, is that there’s still no satisfying solution for quota support in WebDAV, except for using patched mod_dav and Apache versions.

As a base system, i’m using CentOS 5.2

Apache

First, we’re going to install Apache, and configure the stuff

# yum install httpd
# vi /etc/httpd/conf/httpd.conf

Make sure the mod_dav and mod_dav_fs modules are loaded in the configuration file

LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so

<IfModule mod_dav_fs.c>
    DAVLockDB /var/lib/dav/lockdb
</IfModule>

The last section is there by default, but i’ll just post what’s really needed to get things working.

Now, we’re going to build the VirtualHost

<VirtualHost *:80>
    ServerName          weave.yourdomain.com
    DocumentRoot        /home/www/weave.yourdomain.com/www
    ErrorLog            /var/log/httpd/weave_yourdomain_com-error.log
    CustomLog           /var/log/httpd/weave_yourdomain_com-access.log combined
    <Directory "/home/www/weave.yourdomain.com/www">
        Options Indexes FollowSymLinks
        AllowOverride AuthConfig Limit
        Order allow,deny
        Allow from all
        AuthType Basic
        AuthName "WebDAV Restricted"
        AuthUserFile /home/www/weave.yourdomain.com/passwords
        require valid-user
    </Directory>
    <Location />
        DAV On
    </Location>

</VirtualHost>

As you can see, we’re using the directory /home/www/weave.yourdomain.com/www as our DocumentRoot. Valid users from the file /home/www/weave.yourdomain.com/passwords can browse to the DocumentRoot. We will restrict further user-access by using .htaccess files in the “users” directory lateron.

The <Location /> statement enables DAV on the DocumentRoot.

Now, let’s save the thing and create the necessary directories:

cd /home/www
mkdir -p weave.yourdomain.com/www/user/remco
chown -R apache:apache weave.yourdomain.com

For each user, we’ll create a .htaccess file in their directory:

cd /home/www/weave.yourdomain.com/www/user/remco
vi .htaccess

    require user remco

chown apache:apache .htaccess

Finally, we’ll make the passwords file:

htpasswd -c /home/www/weave.yourdomain.com/passwords remco
New password:
Re-type new password: 

That’s it for the installation. Next up: Weave!

Weave

I’m using Weave 0.2.7, downloaded from http://people.mozilla.com/~cbeard/weave/dist/
If you never used Weave before. It’s necessary to first make a profile at Mozilla. After Weave is succesfully configured and syncing to a Mozilla server, you can change properties.

If you have configured Weave, click on the Weave logo in the bottom right of your screen and select ‘Preferences’. After that, sign out on your current Weave login at Mozilla. Click on the Advanced tab and change your Server Location to http://weave.yourdomain.com and start a Sign In.

Firefox Weave Preferences

Et Voila! You are connected to your own Weave WebDAV server. Start syncing at real speeds :-)
If you encounter problems, you can always look at the activity log. If you STILL encounter problems, try to flush server data.

Weave Debugging Tools

Weave over HTTPS / SSL

If you want to have a secure connection, you will need SSL for that. Installation is already done when you have installed Apache on CentOS 5. If you have doubt, check to see if you have mod_ssl and openssl installed with Yum or whatever tool you’re using.

To use SSL, you have to create the next VirtualHost next to the VirtualHost you already created on port 80. Ofcourse you can also completely disable the VirtualHost on port 80 if you really really don’t want a plain connection.

The configuration you have to add is the following :

<VirtualHost *:443>
        ServerName      weave.yourcomain.com
        DocumentRoot    /home/www/weave.yourdomain.com/www
        ErrorLog                /var/log/httpd/weave_yourdomain_com-error.log
        CustomLog               /var/log/httpd/weave_yourdomain_com-access.log combined
    <Directory "/home/www/weave.yourdomain.com/www">
        SSLRequireSSL
        Options Indexes FollowSymLinks
        AllowOverride AuthConfig Limit
        Order allow,deny
        Allow from all
        AuthType Basic
        AuthName "WebDAV Restricted"
        AuthUserFile /home/www/weave.yourdomain.com/passwords
        require valid-user
    </Directory>
    <Location />
        DAV On
    </Location>
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
    SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>
SetEnvIf User-Agent ".*MSIE.*" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0
</VirtualHost>


Note

Note that when you are using a self-signed certificate (like i do), you need to browse to https://weave.yourdomain.com/ and accept the certificate, before it will work in Weave. If you don’t do this, Weave will give you the error “Username / password incorrect”.

Note #2

If you happen to be running Weave 0.2.5 and notice a huge memory and CPU increase, disable the TAB synchronization. There’s a known bug in 0.2.5 that eats your memory. 0.2.6 solves this issue.

Download Weave now at:
http://people.mozilla.com/~cbeard/weave/dist/latest-weave.xpi

Thunderbird?
I also started a blog about using Weave in Thunderbird. You can see it here.

Categories: SysAdmin Tags: