Saturday, September 24, 2011

Setting up your own NTP server on RHEL6

1. Install ntp-4.2.4p8-2.el6.x86_64.rpm
2. Edit /etc/ntp.conf and uncomment the following two lines
        #server  127.127.1.0 # local clock
        #fudge 127.127.1.0 stratum 10
3. service ntpd start



On the client machine
1. Edit /etc/ntp.conf and configure
    server 192.168.240.72 # the ip address of the local ntp server
2. service ntpdate start

eclipse todo


Wednesday, May 25, 2011

TPROXY - Transparent proxy - TCP program - RHEL6

tcp_tproxy.c

/*
 * # iptables -t mangle -N DIVERT
 * # iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
 * # iptables -t mangle -A DIVERT -j MARK --set-mark 1
 * # iptables -t mangle -A DIVERT -j ACCEPT
 * # ip rule add fwmark 1 lookup 100
 * # ip route add local 0.0.0.0/0 dev lo table 100
 * # iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 9401
 *
 */
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <limits.h>
#include <linux/netfilter_ipv4.h>

int handle_client (int c, struct sockaddr_in *clntaddr);
int tunnel_transparently (int c, struct sockaddr_in *clntaddr, struct sockaddr_in *dstaddr);

int main (int argc, char **argv)
{
        int                     s;
        int                     c;
        short int               port;
        struct sockaddr_in      servaddr;
        struct sockaddr_in      clntaddr;
        int                     n;
        int                     ret;
        struct msghdr           msg;
        char                    cntrlbuf[64];
        struct iovec            iov[1];
        char                    *endptr;

        if (argc < 2)
        {
                printf ("usage: %s <port>\n", argv[0]);
                return -1;
        }

        port = strtol (argv[1], &endptr, 0);
        if (*endptr || port <= 0)
        {
                fprintf (stderr, "invalid port number %s.\n", argv[1]);
                return -2;
        }

        if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0)
        {
                fprintf (stderr, "error creating listening socket.\n");
                return -3;
        }

        n=1;
        setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
        setsockopt(s, SOL_SOCKET, SO_BROADCAST, &n, sizeof(n));

        /* Enable TPROXY IP preservation */
        n=1;
        ret = setsockopt (s, SOL_IP, IP_TRANSPARENT, &n, sizeof(int));
        if (ret != 0)
        {
                fprintf (stderr, "error setting transparency for listening socket. err (#%d %s)\n", errno, strerror(errno));
                close (s);
                return -4;
        }

        memset (&servaddr, 0, sizeof (servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl (INADDR_ANY);
        servaddr.sin_port = htons (port);


        if (bind (s, (struct sockaddr *) &servaddr, sizeof (servaddr)) < 0)
        {
                fprintf (stderr, "error calling bind()\n");
                return -6;
        }

        listen (s, 1024);

        while (1)
        {
                n=sizeof(clntaddr);
                if ((c = accept (s, (struct sockaddr *)&clntaddr, &n)) < 0)
                {
                        fprintf (stderr, "error calling accept()\n");
                        break;
                }

                handle_client (c, &clntaddr);
        }

        close (s);

        return 0;
}

int handle_client (int c, struct sockaddr_in *clntaddr)
{
        struct sockaddr_in      dstaddr={0,};
        int                     ret;
        int                     n;

        /* get original destination address */
        n=sizeof(struct sockaddr_in);
        ret = getsockopt (c, SOL_IP, IP_ORIGDSTADDR, &dstaddr, &n); // IP_ORIGDSTADDR = 20
        //ret = getsockopt (c, SOL_IP, SO_ORIGINAL_DST, &dstaddr, &n); // SO_ORIGINAL_DST = 80

        if (ret != 0)
        {
                fprintf (stderr, "error getting original destination address. err (#%d %s)\n", errno, strerror(errno));
                close (c);
                return -1;
        }

        dstaddr.sin_family = AF_INET;
        printf ("original destination address %X:%d\n", dstaddr.sin_addr.s_addr, dstaddr.sin_port);

        ret = tunnel_transparently (c, clntaddr, &dstaddr);
        if (ret <= 0)
        {
                close (c);
                return -2;
        }

        close (c);
        return 0;
}

int tunnel_transparently (int c, struct sockaddr_in *clntaddr, struct sockaddr_in *dstaddr)
{
        int     d;
        int     n;
        int     ret;

        if (clntaddr == NULL || dstaddr == NULL)
        {
                return -1;
        }

        d = socket (AF_INET, SOCK_STREAM, 0);
        if (d == -1)
        {
                fprintf (stderr, "error creating socket (#%d %s)\n", errno, strerror(errno));
                return -2;
        }

        n=1;
        ret = setsockopt (d, SOL_IP, IP_TRANSPARENT, &n, sizeof(int));
        if (ret != 0)
        {
                fprintf (stderr, "error setting transparency towards destination. err (#%d %s)\n", errno, strerror(errno));
                close (d);
                return -3;
        }

        ret = bind (d, (struct sockaddr *)clntaddr, sizeof (struct sockaddr_in));
        if (ret != 0)
        {
                fprintf (stderr, "error binding to client . err (#%d %s)\n", errno, strerror(errno));
                close (d);
                return -4;
        }

        ret = connect (d, (struct sockaddr *)dstaddr, sizeof (*dstaddr));
        if (ret != 0)
        {
                fprintf (stderr, "error connecting to detination. err (#%d %s)\n", errno, strerror(errno));
                close (d);
                return -5;
        }
        // TODO: send / recv
        //

        close (d);

        return 0;
}

Makefile

CFLAGS  += -g

all:    tcp_tproxy udp_tproxy

tcp_tproxy:     tcp_tproxy.o
        $(CC) -o $@ tcp_tproxy.o

udp_tproxy:     udp_tproxy.o
        $(CC) -o $@ udp_tproxy.o

clean:
        -@rm *.o

distclean:      clean
        -@rm tcp_tproxy udp_tproxy

Tuesday, May 24, 2011

TPROXY - Transparent proxy - UDP program - RHEL6

udp_tproxy.c

/*
 * # iptables -t mangle -N DIVERT
 * # iptables -t mangle -A PREROUTING -p udp -m socket -j DIVERT
 * # iptables -t mangle -A DIVERT -j MARK --set-mark 1
 * # iptables -t mangle -A DIVERT -j ACCEPT
 * # ip rule add fwmark 1 lookup 100
 * # ip route add local 0.0.0.0/0 dev lo table 100
 * # iptables -t mangle -A PREROUTING -p udp --dport 9201 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 19201
 *
 * Tested on RHEL 6
 */

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>

#define MAX_RECV_BUF    (1000)

int handle_msg (struct msghdr *msg);
int send_transparently (struct msghdr *msg, struct sockaddr_in *dstaddr);

int main (int argc, char **argv)
{
        int                     s;
        short int               port;
        struct sockaddr_in      servaddr;
        struct sockaddr_in      clntaddr;
        int                     n;
        int                     ret;
        struct msghdr           msg;
        char                    cntrlbuf[64];
        struct iovec            iov[1];
        char                    buffer[MAX_RECV_BUF];
        char                    *endptr;

        if (argc < 2)
        {
                printf ("usage: %s <port>\n", argv[0]);
                return -1;
        }

        port = strtol (argv[1], &endptr, 0);
        if (*endptr || port <= 0)
        {
                fprintf (stderr, "invalid port number %s.\n", argv[1]);
                return -2;
        }

        if ((s = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
        {
                fprintf (stderr, "error creating listening socket.\n");
                return -3;
        }

        n=1;
        setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
        setsockopt(s, SOL_SOCKET, SO_BROADCAST, &n, sizeof(n));

        n=1;
        ret = setsockopt (s, SOL_IP, IP_TRANSPARENT, &n, sizeof(int));
        if (ret != 0)
        {
                fprintf (stderr, "error setting transparency for listening socket. err (#%d %s)\n", errno, strerror(errno));
                close (s);
                return -4;
        }
        n=1;
        ret = setsockopt (s, IPPROTO_IP, IP_RECVORIGDSTADDR, &n, sizeof(int));
        if (ret != 0)
        {
                fprintf (stderr, "error setting the listening socket to IP_TRANSPARENT. err (#%d %s)\n", errno, strerror(errno));
                close (s);
                return -5;
        }

        memset (&servaddr, 0, sizeof (servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl (INADDR_ANY);
        servaddr.sin_port = htons (port);


        if (bind (s, (struct sockaddr *) &servaddr, sizeof (servaddr)) < 0)
        {
                fprintf (stderr, "error calling bind()\n");
                return -6;
        }

        while (1)
        {
                msg.msg_name = &clntaddr;
                msg.msg_namelen = sizeof(clntaddr);
                msg.msg_control = cntrlbuf;
                msg.msg_controllen = sizeof(cntrlbuf);
                iov[0].iov_base = buffer;
                iov[0].iov_len = sizeof (buffer);
                msg.msg_iov = iov;
                msg.msg_iovlen = 1;
                ret = recvmsg (s, &msg, 0);
                if (ret <= 0)
                {
                        fprintf (stderr, "error calling recvmsg(). err (#%d %s)\n", errno, strerror(errno));
                        break;
                }

                msg.msg_iov[0].iov_len = ret;
                handle_msg (&msg);
        }

        close (s);

        return 0;
}

int handle_msg (struct msghdr *msg)
{
        struct sockaddr_in      *clntaddr;
        struct sockaddr_in      dstaddr={0,};
        struct cmsghdr          *cmsg;
        int                     ret;
        int                     found=0;

        clntaddr =  msg->msg_name;
        printf ("recvd msg from %X:%d\n", clntaddr->sin_addr.s_addr, clntaddr->sin_port);

        /* get original destination address */
        for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg))
        {
                if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVORIGDSTADDR)
                {
                        memcpy (&dstaddr, CMSG_DATA(cmsg), sizeof (struct sockaddr_in));
                        dstaddr.sin_family = AF_INET;
                        printf ("original dst address %X:%d\n", dstaddr.sin_addr.s_addr, dstaddr.sin_port);
                        found = 1;
                }
        }

        if (! found)
        {
                return -1;
        }

        ret = send_transparently (msg, &dstaddr);
        if (ret <= 0)
        {
                return -2;
        }

        return 0;
}

int send_transparently (struct msghdr *msg, struct sockaddr_in *dstaddr)
{
        int     d;
        int     n;
        int     ret;

        if (msg == NULL || dstaddr == NULL)
        {
                return -1;
        }

        d = socket (AF_INET, SOCK_DGRAM, 0);
        if (d == -1)
        {
                fprintf (stderr, "error creating socket (#%d %s)\n", errno, strerror(errno));
                return -2;
        }

        n=1;
        ret = setsockopt (d, SOL_IP, IP_TRANSPARENT, &n, sizeof(int));
        if (ret != 0)
        {
                fprintf (stderr, "error setting transparency towards destination. err (#%d %s)\n", errno, strerror(errno));
                close (d);
                return -3;
        }

        ret = bind (d, (struct sockaddr *)msg->msg_name, sizeof (struct sockaddr_in));
        if (ret != 0)
        {
                fprintf (stderr, "error binding to client . err (#%d %s)\n", errno, strerror(errno));
                close (d);
                return -4;
        }

        ret = sendto (d, msg->msg_iov[0].iov_base, msg->msg_iov[0].iov_len, 0, (struct sockaddr *)dstaddr, sizeof (*dstaddr));
        if (ret <= 0)
        {
                fprintf (stderr, "error sending to detination. err (#%d %s)\n", errno, strerror(errno));
                close (d);
                return -5;
        }

        close (d);

        return 0;
}

Monday, April 25, 2011

SSH - Passing Unix login passwords through shell scripts

Ref: http://nixcraft.com/shell-scripting/4489-ssh-passing-unix-login-passwords-through-shell-scripts.html

You need to create a login file as follows login.txt:
Code:
server1|user|password

A shell script as follows (sshlogin.sh):
Code:
#!/bin/bash
FILE=login.txt
CONNECT=sshlogin.exp
SERVERNAME=$1
MyServer=""
MyUser=""
MyPassword=""
exec 3<&0
exec 0<$FILE
while read line
do
        MyServer=$(echo $line | cut -d'|' -f1)
        MyUser=$(echo $line | cut -d'|' -f2)
        MyPassword=$(echo $line | cut -d'|' -f3)
        if [ "$SERVERNAME" == "$MyServer" ];
        then
           echo "Running ssh $MyUser@$MyServer..."
          $CONNECT $MyPassword $MyServer $MyUser
        fi
done
exec 0<&3
echo "$SERVERNAME not found in login.txt file"
Modified sshlogin.exp from Ssh login expect script to supply password

In order to use following script you need to install expect tool, use apt-get or yum command!

Code:
#!/usr/bin/expect -f
# Expect script to supply root/admin password for remote ssh server 
# and execute command.
# This script needs three argument to(s) connect to remote server:
# password = Password of remote UNIX server, for root user.
# ipaddr = IP Addreess of remote UNIX server, no hostname
# scriptname = Path to remote script which will execute on remote server
# For example:
#  ./sshlogin.exp password 192.168.1.11 who 
# ------------------------------------------------------------------------
# Copyright (c) 2004 nixCraft project <http://cyberciti.biz/fb/>
# This script is licensed under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# ----------------------------------------------------------------------
# set Variables
set password [lrange $argv 0 0] 
set ipaddr [lrange $argv 1 1]   
set username [lrange $argv 2 2] 
set timeout -1   
# now connect to remote UNIX box (ipaddr) with given script to execute
spawn ssh $username@$ipaddr
match_max 100000
# Look for passwod prompt
expect "*?assword:*"
# Send password aka $password 
send -- "$password\r"
# send blank line (\r) to make sure we get back to gui
send -- "\r"
expect eof
To run script - set permissions
Code:
chmod +x sshlogin.sh
chmod +x  sshlogin.exp
Test it by connecting 127.0.0.1
Code:
./sshlogin 127.0.0.1