May 9, 2016

Example code of IPv4 and IPv6 using FREEBIND and IP_TRANSPARENT socket options to send packets using a non-local IP address



http://lists.openwall.net/netdev/2011/11/02/4

Use  IP_PKTINFO to  set the source IP address if you do not bind it to a particular address.

http://man7.org/linux/man-pages/man7/ip.7.html

Date: Tue, 1 Nov 2011 17:57:07 -0700
From: Maciej Żenczykowski <zenczykowski@...il.com>
To: Linux NetDev <netdev@...r.kernel.org>
Subject: On IP_FREEBIND and IPv6...

Short summary:
  IPV6 + IP_FREEBIND doesn't work the way IPV4 + IP_FREEBIND does.
  The native IPv6 bind path ignores 'freebind', but honours 'transparent'.
  The native and dual-stack IPv4 bind paths honour both.

Does anyone know if this was a (security?) feature?  Or is this just a bug?

I'll follow this up with a patch to support freebind for v6 bind (and
another one for v6 udp sendmsg).
Unless I hear some compelling story about why stuff is the way it is.

---

Please find test program source later on.

It basically does:
   for test_mode in {native_ipv4, ipv4_on_ipv6_socket, native_ipv6} do:
       create a udp socket
       set IP_FREEBIND=1
       set IP_TRANSPARENT=1 (will fail if not root, ignore failure)
       bind socket to an IP address we don't own (one of: 1.2.3.4,
::FFFF:1.2.3.4, 2001:4860:DEAD:CAFE::6006:13) [fails without root for
native ipv6]
       send a packet to another IP address (one of: 5.6.7.8,
::FFFF:5.6.7.8, 2001:4860:DEAD:BEEF::6006:13)

Running it generates:

$ ./test
setsockopt(TRANSPARENT=1): Operation not permitted [requires root]
setsockopt(TRANSPARENT=1): Operation not permitted [requires root]
setsockopt(TRANSPARENT=1): Operation not permitted [requires root]
bind(): Cannot assign requested address [native ipv6 bind does not
honour IP_FREEBIND, does honour IP{,V6}_TRANSPARENT]
$ sudo ./test
<no errors, everything succeeds, including bind native ipv6>

While running tcpdump shows:
# tcpdump -s 1555 -n -nn -i eth0 port 11111 or port 22222

>From ./a [ie. with IP_FREEBIND=1, IP_TRANSPARENT=0]:

IP 1.2.3.4.11111 > 5.6.7.8.22222: UDP, length 6 [native IPv4]
IP 1.2.3.4.11111 > 5.6.7.8.22222: UDP, length 6 [dual stack IPv4 on IPv6 socket]
IP6 [machines_true_ipv6_address].51912 >
2001:4860:dead:beef::6006:13.22222: UDP, length 6 [native IPv6, wrong
source since bind failed]

>From sudo ./a [ie. with IP_FREEBIND=1, IP_TRANSPARENT=1]:

IP 1.2.3.4.11111 > 5.6.7.8.22222: UDP, length 6 [native IPv4]
IP 1.2.3.4.11111 > 5.6.7.8.22222: UDP, length 6 [dual stack IPv4 on IPv6 socket]
IP6 2001:4860:dead:cafe::6006:13.vce >
2001:4860:dead:beef::6006:13.22222: UDP, length 6 [native IPv6]

This seems to prove that IP_TRANSPARENT requires root - this is as
expected, while IP_FREEBIND does not require root - again as expected.
However, as apparent above, we are successfully spoofing outgoing
source address on IPv4 UDP (whether native IPv4 or dual-stack IPv4
doesn't matter),
but there doesn't seem to be a way to do this with native IPv6.

ie. the native IPv6 bind path ignores the "freebind" setting, but does
honour the "transparent", while the IPv4 code paths honour both.

- Maciej

---
#include <string.h>
#include <stdio.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#define NATIVE_IPv4 0
#define DUAL_STACK  1
#define NATIVE_IPv6 2

int main(int argc, char const * argv[], char const * envp[]) {
  struct sockaddr_in saddr4, daddr4;
  struct sockaddr_in6 saddr6, daddr6;
  int fd, rv, v, mode;

  for (mode = 0; mode <= 2; ++mode) {

    if (mode == NATIVE_IPv4) {
      fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
      if (fd < 0) perror("socket(IPv4 UDP)");
    } else {
      fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
      if (fd < 0) perror("socket(IPv6 UDP)");
    }

    v = 1;
    rv = setsockopt(fd, SOL_IP, IP_FREEBIND, &v, sizeof(v));
    if (rv < 0) perror("setsockopt(FREEBIND=1)");

    v = 1;
    rv = setsockopt(fd, SOL_IP, IP_TRANSPARENT, &v, sizeof(v));
    if (rv < 0) perror("setsockopt(TRANSPARENT=1)");

    if (mode == NATIVE_IPv4) {
      memset(&saddr4, 0, sizeof(saddr4));
      memset(&daddr4, 0, sizeof(daddr4));
      saddr4.sin_family = AF_INET;
      daddr4.sin_family = AF_INET;
      saddr4.sin_port = htons(11111);
      daddr4.sin_port = htons(22222);
      inet_pton(AF_INET, "1.2.3.4", &saddr4.sin_addr.s_addr);
      inet_pton(AF_INET, "5.6.7.8", &daddr4.sin_addr.s_addr);

      rv = bind(fd, (struct sockaddr const *)&saddr4, sizeof(saddr4));
      if (rv < 0) perror("bind()");

      rv = sendto(fd, "Hello!", 6, 0, (struct sockaddr const
*)&daddr4, sizeof(daddr4));
      if (rv < 0) perror("write");
    } else {
      memset(&saddr6, 0, sizeof(saddr6));
      memset(&daddr6, 0, sizeof(daddr6));
      saddr6.sin6_family = AF_INET6;
      daddr6.sin6_family = AF_INET6;
      saddr6.sin6_port = htons(11111);
      daddr6.sin6_port = htons(22222);
      //saddr6.sin6_flowinfo = 0;
      //daddr6.sin6_flowinfo = 0;
      if (mode == DUAL_STACK) {
        inet_pton(AF_INET6, "::FFFF:1.2.3.4", &saddr6.sin6_addr);
        inet_pton(AF_INET6, "::FFFF:5.6.7.8", &daddr6.sin6_addr);
      } else {
        inet_pton(AF_INET6, "2001:4860:DEAD:CAFE::6006:0013",
&saddr6.sin6_addr);
        inet_pton(AF_INET6, "2001:4860:DEAD:BEEF::6006:0013",
&daddr6.sin6_addr);
      }
      //saddr6.sin6_scope_id = 0;
      //daddr6.sin6_scope_id = 0;

      rv = bind(fd, (struct sockaddr const *)&saddr6, sizeof(saddr6));
      if (rv < 0) perror("bind()");

      rv = sendto(fd, "Hello!", 6, 0, (struct sockaddr const
*)&daddr6, sizeof(daddr6));
      if (rv < 0) perror("write");
    }

    rv = close(fd);
    if (rv < 0) perror("close");
  }

  return 0;
}
--


BELOW is my adapted version:

#include <string.h>
#include <stdio.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
//#include <linux/in.h>
#include <arpa/inet.h>

#define NATIVE_IPv4 0
#define DUAL_STACK  1
#define NATIVE_IPv6 2

#if 1
#if !defined(IP_FREEBIND)
#define IP_FREEBIND 15
#endif /* !IP_FREEBIND */
#if !defined(IP_TRANSPARENT)
#define IP_TRANSPARENT 19
#endif /* !IP_TRANSPARENT */
#endif

#define IPV6_TRANSPARENT        75

int main(int argc, char const * argv[], char const * envp[]) {
        struct sockaddr_in saddr4, daddr4;
        struct sockaddr_in6 saddr6, daddr6;
        int fd, rv, v, mode;

        for (mode = 2; mode <= 2; ++mode) {

                if (mode == NATIVE_IPv4) {
                        fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
                        if (fd < 0) perror("socket(IPv4 UDP)");
                } else {
                        fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
                        if (fd < 0) perror("socket(IPv6 UDP)");
                }

                v = 1;
                rv = setsockopt(fd, SOL_IP, IP_FREEBIND, &v, sizeof(v));
                if (rv < 0) perror("setsockopt(FREEBIND=1)");

                if (mode == NATIVE_IPv4) {
                        v = 1;
                        rv = setsockopt(fd, SOL_IP, IP_TRANSPARENT, &v, sizeof(v));
                        if (rv < 0) perror("setsockopt(TRANSPARENT=1)");
                }else{
                        v = 1;
                        rv = setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &v, sizeof(v));
                        if (rv < 0) perror("setsockopt ipv6 (TRANSPARENT=1)");
                }

                if (mode == NATIVE_IPv4) {
                        memset(&saddr4, 0, sizeof(saddr4));
                        memset(&daddr4, 0, sizeof(daddr4));
                        saddr4.sin_family = AF_INET;
                        daddr4.sin_family = AF_INET;
                        saddr4.sin_port = htons(11111);
                        daddr4.sin_port = htons(22222);
                        inet_pton(AF_INET, "1.2.3.4", &saddr4.sin_addr.s_addr);
                        inet_pton(AF_INET, "5.6.7.8", &daddr4.sin_addr.s_addr);

                        rv = bind(fd, (struct sockaddr const *)&saddr4, sizeof(saddr4));
                        if (rv < 0) perror("bind()");

                        rv = sendto(fd, "Hello!", 6, 0, (struct sockaddr const
                                                *)&daddr4, sizeof(daddr4));
                        if (rv < 0) perror("write");
                } else {
                        memset(&saddr6, 0, sizeof(saddr6));
                        memset(&daddr6, 0, sizeof(daddr6));
                        saddr6.sin6_family = AF_INET6;
                        daddr6.sin6_family = AF_INET6;
                        saddr6.sin6_port = htons(11111);
                        daddr6.sin6_port = htons(22222);
                        //saddr6.sin6_flowinfo = 0;
                        //daddr6.sin6_flowinfo = 0;
                        if (mode == DUAL_STACK) {
                                inet_pton(AF_INET6, "::FFFF:1.2.3.4", &saddr6.sin6_addr);
                                inet_pton(AF_INET6, "::FFFF:5.6.7.8", &daddr6.sin6_addr);
                        } else {
                                inet_pton(AF_INET6, "2001:4860:DEAD:CAFE::6006:0013",
                                                &saddr6.sin6_addr);
                                inet_pton(AF_INET6, "2001:4860:DEAD:BEEF::6006:0013",
                                                &daddr6.sin6_addr);
                        }
                        //saddr6.sin6_scope_id = 0;
                        //daddr6.sin6_scope_id = 0;

                        rv = bind(fd, (struct sockaddr const *)&saddr6, sizeof(saddr6));
                        if (rv < 0) perror("bind()");

                        rv = sendto(fd, "Hello!", 6, 0, (struct sockaddr const
                                                *)&daddr6, sizeof(daddr6));
                        if (rv < 0) perror("write");
                }

                rv = close(fd);
                if (rv < 0) perror("close");
        }

        return 0;

April 28, 2016

customize golang tls listener

How ListenAndServeTLS works in Golang

  1. it creates a struct of http.Server type, and then calls the server.ListenAndServe method
  2. http.server.ListenAndServeTLS
    1. clone server.TLSConfig
    2. if tls config has no certs OR a certfile is specified, load certs
    3. create a TLS socket that listens on the TCP port
    4. call server.Serve using that socket
  3. Server.serve
    1. Accept the new connection, returns http.conn
    2. http.conn.serve()


The customize this, one could write his own function like this:

   srv := &Server{Addr: addr, Handler: handler}
    addr := srv.Addr
    if addr == "" {
        addr = ":https"
    }
    config := cloneTLSConfig(srv.TLSConfig)
    if config.NextProtos == nil {
        config.NextProtos = []string{"http/1.1"}
    }

    if len(config.Certificates) == 0 || certFile != "" || keyFile != "" {
        var err error
        config.Certificates = make([]tls.Certificate, 1)
        config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
        if err != nil {
            return err
        }
    }

    ln, err := net.Listen("tcp", addr)
    if err != nil {
        return err
    }

    tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, config)
    return srv.Serve(tlsListener)



April 22, 2016

ipset netlink data structure

header:
\x4c\x00 \x00\x00 total length
\x09\x06 type=09 CMD_ADD \x05\x02 flags:0x0205 request/ack/return-all-matching
\xbb\x83\x1a\x57 seq
\x00\x00\x00\x00 port id

extra header
\x02\x00\x00\x00

payload, in the form of Leng-Type-Value
(len and type are 2 bytes, len includes itself and type. 0 Padded to 4-byte alignment)
Type flags:
   0x80: NEST structure
   0x40: Network Order

\x05\x00 \x01\x00 \x06 \x00\x00\x00 PROTOCOL=6
\x0a\x00 \x02\x00 \x70\x61\x69\x72\x31\x00\x00\x00 SETNAME=pair1
\x24\x00 \x07\x80 IPSET_ATTR_DATA
\x0c\x00 \x01\x80\ IPSET_ATTR_IP
x08\x00\x01\x40\x02\x02\x02\x02 IPV4 2.2.2.2
\x0c\x00\x14\x80 IPSET_ATTR_IP2
\x08\x00\x01\x40 \x04\x04\x04\x04 IP 4.4.4.4
\x08\x00\x09\x40 \x00\x00\x00\x00 IPSTE_ATTR_LINENO 0, network order


== update on 12/13/2018
enum ipset_cmd {
    IPSET_CMD_NONE,
    IPSET_CMD_PROTOCOL, /* 1: Return protocol version */
    IPSET_CMD_CREATE,   /* 2: Create a new (empty) set */
    IPSET_CMD_DESTROY,  /* 3: Destroy a (empty) set */
    IPSET_CMD_FLUSH,    /* 4: Remove all elements from a set */
    IPSET_CMD_RENAME,   /* 5: Rename a set */
    IPSET_CMD_SWAP,     /* 6: Swap two sets */
    IPSET_CMD_LIST,     /* 7: List sets */
    IPSET_CMD_SAVE,     /* 8: Save sets */
    IPSET_CMD_ADD,      /* 9: Add an element to a set */
    IPSET_CMD_DEL,      /* 10: Delete an element from a set */
    IPSET_CMD_TEST,     /* 11: Test an element in a set */
    IPSET_CMD_HEADER,   /* 12: Get set header data only */
    IPSET_CMD_TYPE,     /* 13: Get set type */
    IPSET_MSG_MAX,      /* Netlink message commands */

    /* Commands in userspace: */
    IPSET_CMD_RESTORE = IPSET_MSG_MAX, /* 14: Enter restore mode */
    IPSET_CMD_HELP,     /* 15: Get help */
    IPSET_CMD_VERSION,  /* 16: Get program version */
    IPSET_CMD_QUIT,     /* 17: Quit from interactive mode */

    IPSET_CMD_MAX,

    IPSET_CMD_COMMIT = IPSET_CMD_MAX, /* 18: Commit buffered commands */
};

command level attributes:
IPSET_ATTR_PROTOCOL,    /* 1: Protocol version */
IPSET_ATTR_SETNAME, /* 2: Name of the set */
IPSET_ATTR_TYPENAME,    /* 3: Typename */
IPSET_ATTR_SETNAME2 = IPSET_ATTR_TYPENAME, /* Setname at rename/swap */
IPSET_ATTR_REVISION,    /* 4: Settype revision */
IPSET_ATTR_FAMILY,  /* 5: Settype family */
IPSET_ATTR_FLAGS,   /* 6: Flags at command level */
IPSET_ATTR_DATA,    /* 7: Nested attributes */
IPSET_ATTR_ADT,     /* 8: Multiple data containers */
IPSET_ATTR_LINENO,  /* 9: Restore lineno */
IPSET_ATTR_PROTOCOL_MIN, /* 10: Minimal supported version number */

Nested attributes:
/* CADT specific attributes */
IPSET_ATTR_IP = IPSET_ATTR_UNSPEC + 1,
IPSET_ATTR_IP_FROM = IPSET_ATTR_IP,
IPSET_ATTR_IP_TO,   /* 2 */
IPSET_ATTR_CIDR,    /* 3 */
IPSET_ATTR_PORT,    /* 4 */
IPSET_ATTR_PORT_FROM = IPSET_ATTR_PORT,
IPSET_ATTR_PORT_TO, /* 5 */
IPSET_ATTR_TIMEOUT, /* 6 */
IPSET_ATTR_PROTO,   /* 7 */
IPSET_ATTR_CADT_FLAGS,  /* 8 */
IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO, /* 9 */
/* Reserve empty slots */
IPSET_ATTR_CADT_MAX = 16, 0x10
/* Create-only specific attributes */
IPSET_ATTR_GC,              //0x11
IPSET_ATTR_HASHSIZE,        //0x12
IPSET_ATTR_MAXELEM,         //0x13
IPSET_ATTR_NETMASK,         //0x14
IPSET_ATTR_PROBES,          //0x15
IPSET_ATTR_RESIZE,          //0x16
IPSET_ATTR_SIZE,            //0x17
/* Kernel-only */
IPSET_ATTR_ELEMENTS,
IPSET_ATTR_REFERENCES,
IPSET_ATTR_MEMSIZE,
__IPSET_ATTR_CREATE_MAX,


set type family list:
NFPROTO_UNSPEC =  0, //can be used to include both v4 and v6
NFPROTO_IPV4   =  2,
NFPROTO_ARP    =  3,
NFPROTO_BRIDGE =  7,
NFPROTO_IPV6   = 10,
NFPROTO_DECNET = 12,

#define NLA_F_NESTED        (1 << 15)
#define NLA_F_NET_BYTEORDER (1 << 14)


* strace version 4.23 and upper parses netlink messages. However, the parsing cannot seem to be disabled. You will need the lower version to output hex instead of parsing it.

=== cmd: ipset create filtered hash:ip,port,ip timeout 60

check type is supported?

sendto(3, {{len=56, type=NFNL_SUBSYS_IPSET<<8|IPSET_CMD_TYPE, flags=NLM_F_REQUEST, seq=1544742655, pid=0}, {nfgen_family=AF_INET, version=NFNETLINK_V0, res_id=htons(0), 
[{{nla_len=5, nla_type=0x1}, "\x06"}, protocol version
 {{nla_len=20, nla_type=0x3}, "\x68\x61\x73\x68\x3a\x69\x70\x2c\x70\x6f\x72\x74\x2c\x69\x70\x00"},  type name
 {{nla_len=5, nla_type=0x5}, "\x02"}, type family, 2 is ipv4
 ]}, 56, 0, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 56
recvmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base={{len=72, type=NFNL_SUBSYS_IPSET<<8|IPSET_CMD_TYPE, flags=0, seq=1544742655, pid=23011}, {nfgen_family=AF_INET, version=NFNETLINK_V0, res_id=htons(0), [{{nla_len=5, nla_type=NFNETLINK_V1}, "\x06"}, {{nla_len=20, nla_type=0x3}, "\x68\x61\x73\x68\x3a\x69\x70\x2c\x70\x6f\x72\x74\x2c\x69\x70\x00"}, {{nla_len=5, nla_type=0x5}, "\x02"}, {{nla_len=5, nla_type=0x4}, "\x05"}, {{nla_len=5, nla_type=0xa}, "\x00"}]}, iov_len=256}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 72

sendto(3, {{len=92, type=NFNL_SUBSYS_IPSET<<8|IPSET_CMD_CREATE, flags=NLM_F_REQUEST|NLM_F_ACK|0x600, seq=1544742656, pid=0}, {nfgen_family=AF_INET, version=NFNETLINK_V0, res_id=htons(0), [
{{nla_len=5, nla_type=NFNETLINK_V1}, "\x06"}, 
{{nla_len=13, nla_type=0x2}, "\x66\x69\x6c\x74\x65\x72\x65\x64\x00"},  set name "filterd"
{{nla_len=20, nla_type=0x3}, "\x68\x61\x73\x68\x3a\x69\x70\x2c\x70\x6f\x72\x74\x2c\x69\x70\x00"},  "hash:ip,port,ip"
{{nla_len=5, nla_type=0x4}, "\x05"},  revision is 5? seems wrong
{{nla_len=5, nla_type=0x5}, "\x02"}, ipv4
{{nla_len=12, nla_type=NLA_F_NESTED|0x7}, "\x08\x00\x06\x40\x00\x00\x00\x3c"} len=8, type=6 (timeout), net-order, 60s
]}, 92, 0, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 92
recvmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base={{len=36, type=NLMSG_ERROR, flags=0, seq=1544742656, pid=23011}, {error=0, msg={len=92, type=NFNL_SUBSYS_IPSET<<8|IPSET_CMD_CREATE, flags=NLM_F_REQUEST|NLM_F_ACK|0x600, seq=1544742656, pid=0}}}, iov_len=4096}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 36




=== cmd: ipset create filtered1 hash:ip,port,ip timeout 60

sendto(3, "\x38\x00\x00\x00\x0d\x06\x01\x00\x22\xe7\x12\x5c\x00\x00\x00\x00\x02\x00\x00\x00\x05\x00\x01\x00\x06\x00\x00\x00\x14\x00\x03\x00\x68\x61\x73\x68\x3a\x69\x70\x2c\x70\x6f\x72\x74\x2c\x69\x70\x00\x05\x00\x05\x00\x02\x00\x00\x00", 56, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 56
recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\x48\x00\x00\x00\x0d\x06\x00\x00\x22\xe7\x12\x5c\x3c\x5b\x00\x00\x02\x00\x00\x00\x05\x00\x01\x00\x06\x00\x00\x00\x14\x00\x03\x00\x68\x61\x73\x68\x3a\x69\x70\x2c\x70\x6f\x72\x74\x2c\x69\x70\x00\x05\x00\x05\x00\x02\x00\x00\x00\x05\x00\x04\x00\x05\x00\x00\x00\x05\x00\x0a\x00\x00\x00\x00\x00", 256}], msg_controllen=0, msg_flags=0}, 0) = 72

sendto(3, "\x5c\x00\x00\x00\x02\x06\x05\x06\x23\xe7\x12\x5c\x00\x00\x00\x00\x02\x00\x00\x00\x05\x00\x01\x00\x06\x00\x00\x00\x0e\x00\x02\x00\x66\x69\x6c\x74\x65\x72\x65\x64\x31\x00\x00\x00\x14\x00\x03\x00\x68\x61\x73\x68\x3a\x69\x70\x2c\x70\x6f\x72\x74\x2c\x69\x70\x00\x05\x00\x04\x00\x05\x00\x00\x00\x05\x00\x05\x00\x02\x00\x00\x00\x0c\x00\x07\x80\x08\x00\x06\x40\x00\x00\x00\x3c", 92, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 92

decoded message:
\x5c\x00\x00\x00 length
\x02\x06 , 0x0602: 0x06 is NFNL_SUBSYS_IPSET, 0x02 is IPSET_CMD_CREATE
#define NFNL_SUBSYS_NONE        0
#define NFNL_SUBSYS_CTNETLINK       1
#define NFNL_SUBSYS_CTNETLINK_EXP   2
#define NFNL_SUBSYS_QUEUE       3
#define NFNL_SUBSYS_ULOG        4
#define NFNL_SUBSYS_OSF         5
#define NFNL_SUBSYS_IPSET       6
#define NFNL_SUBSYS_ACCT        7
#define NFNL_SUBSYS_CTNETLINK_TIMEOUT   8
#define NFNL_SUBSYS_CTHELPER        9
#define NFNL_SUBSYS_COUNT       10

\x05\x06, NLM flags: 0x0605: create | excl | ack |request
/* Flags values */
#define NLM_F_REQUEST       1   /* It is request message.   */
#define NLM_F_MULTI     2   /* Multipart message, terminated by NLMSG_DONE */
#define NLM_F_ACK       4   /* Reply with ack, with zero or error code */
#define NLM_F_ECHO      8   /* Echo this request        */
#define NLM_F_DUMP_INTR     16  /* Dump was inconsistent due to sequence change */
/* Modifiers to GET request */
#define NLM_F_ROOT  0x100   /* specify tree root    */
#define NLM_F_MATCH 0x200   /* return all matching  */
#define NLM_F_ATOMIC    0x400   /* atomic GET       */
#define NLM_F_DUMP  (NLM_F_ROOT|NLM_F_MATCH)
/* Modifiers to NEW request */
#define NLM_F_REPLACE   0x100   /* Override existing        */
#define NLM_F_EXCL  0x200   /* Do not touch, if it exists   */
#define NLM_F_CREATE    0x400   /* Create, if it does not exist */
#define NLM_F_APPEND    0x800   /* Add to end of list       */

\x23\xe7\x12\x5c :seq number
\x00\x00\x00\x00 : port id
\x02\x00\x00\x00 : extra header

\x05\x00 \x01\x00\ x06 length is 5, type is 1, value is 6
\x00\x00\x00, padded to multipe of 4 bytes
\x0e\x00 \x02\x00 \x66\x69\x6c\x74 \x65\x72\x65\x64 \x31\x00\x00\x00, length is 14, type is 2,i.e. set name, name is "filtered1"
\x14\x00 \x03\x00 \x68\x61\x73\x68\x3a\x69\x70\x2c\x70\x6f\x72\x74\x2c\x69\x70\x00
\x05\x00\x04\x00\x05\x00\x00\x00: revision 5
\x05\x00\x05\x00\x02\x00\x00\x00: family 2
\x0c\x00\x07\x80 \x08\x00\x06\x40\x00\x00\x00\x3c, nested attributes, timeout value, networker order of 0x3c

recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\x24\x00\x00\x00\x02\x00\x00\x00\x23\xe7\x12\x5c\x3c\x5b\x00\x00\x00\x00\x00\x00\x5c\x00\x00\x00\x02\x06\x05\x06\x23\xe7\x12\x5c\x00\x00\x00\x00", 4096}], msg_controllen=0, msg_flags=0}, 0) = 36


==cmd: ipset create torlistv6 hash:ip family inet6 hashsize 2048 maxelem 65536
sendto(3, {{len=48, type=NFNL_SUBSYS_IPSET<<8|IPSET_CMD_TYPE, flags=NLM_F_REQUEST, seq=1544745557, pid=0}, {nfgen_family=AF_INET, version=NFNETLINK_V0, res_id=htons(0), [{{nla_len=5, nla_type=NFNETLINK_V1}, "\x06"}, {{nla_len=12, nla_type=0x3}, "\x68\x61\x73\x68\x3a\x69\x70\x00"}, {{nla_len=5, nla_type=0x5}, "\x02"}]}, 48, 0, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 48
recvmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base={{len=64, type=NFNL_SUBSYS_IPSET<<8|IPSET_CMD_TYPE, flags=0, seq=1544745557, pid=19683}, {nfgen_family=AF_INET, version=NFNETLINK_V0, res_id=htons(0), [
{{nla_len=5, nla_type=NFNETLINK_V1}, "\x06"}, 
{{nla_len=12, nla_type=0x3}, "\x68\x61\x73\x68\x3a\x69\x70\x00"}, 
{{nla_len=5, nla_type=0x5}, "\x02"}, 
{{nla_len=5, nla_type=0x4}, "\x04"}, 
{{nla_len=5, nla_type=0xa}, "\x00"}]}, iov_len=256}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 64

sendto(3, {{len=92, type=NFNL_SUBSYS_IPSET<<8|IPSET_CMD_CREATE, flags=NLM_F_REQUEST|NLM_F_ACK|0x600, seq=1544745558, pid=0}, {nfgen_family=AF_INET, version=NFNETLINK_V0, res_id=htons(0), [
{{nla_len=5, nla_type=NFNETLINK_V1}, "\x06"}, 
{{nla_len=14, nla_type=0x2}, "\x74\x6f\x72\x6c\x69\x73\x74\x76\x36\x00"}, 
{{nla_len=12, nla_type=0x3}, "\x68\x61\x73\x68\x3a\x69\x70\x00"}, 
{{nla_len=5, nla_type=0x4}, "\x04"}, 
{{nla_len=5, nla_type=0x5}, "\x0a"}, 
{{nla_len=20, nla_type=NLA_F_NESTED|0x7}, "\x08\x00\x12\x40\x00\x00\x08\x00\x08\x00\x13\x40\x00\x01\x00\x00"}
\x08\x00\x12\x40 \x00\x00\x08\x00, hashsize 0x800
\x08\x00\x13\x40 \x00\x01\x00\x00, maxelem 0x10000
]}, 92, 0, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 92
recvmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base={{len=36, type=NLMSG_ERROR, flags=0, seq=1544745558, pid=19683}, {error=0, msg={len=92, type=NFNL_SUBSYS_IPSET<<8|IPSET_CMD_CREATE, flags=NLM_F_REQUEST|NLM_F_ACK|0x600, seq=1544745558, pid=0}}}, iov_len=4096}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 36


April 7, 2016

curl test api

In curl, use "--data-urlencode" to encode data

use "-G" to send data in "GET" instead of "POST".

curl  -G "https://myserver.com:1234/msg?msgtype=PUSH" --data-urlencode "msg=hello how are you"

March 23, 2016

no trusted RSA public key found, strongswan, IKEv2

My setup:

Linux running strongswan server, 5.3, latest version.
Client is iPhone iOS 9.2

Trying to setup IKEv2 with certificate authentication. MS-CHAPv2 authentication works fine.

Issue: no trusted RSA public key found

After spending hours on the Internet, combing through the strongswan forums and even looking at the source code, I was able to finally find out the issue:

The issue was with the client certificate I generated for iPhone.

The certificate did not have a SAN (Subject Alternative Name). I never knew it was REQUIRED to have one.  This is how the check on the server goes:

1. Server needs to make sure a certificate is received from the client.
2. It then does the following checks:
    - cert is signed with a known CA.
    - cert date is valid
    - IMPORTANT: "local ID" specified on iOS has to be a FQDN, and has to match the SAN in the certificate.  SAN for FQDN starts with "DNS:". In theory, the ID can also be IPv4 address (IP:) or USER_FQDN with is an email address (email:). If no SAN is found in the cert, the server is supposed to match the DN of the cert, but iOS always submit the local ID as FQDN therefore breaking that, and therefore requiring an SAN for the client cert with the "DNS:" name.

strongswan log will not tell you this if the SAN and local ID does not match, even if turning debug level all the way to 3. It will just say "no trusted RSA public key found". Very confusing.

Well, now you know it.

linuc iptables, NAT and bridge interface

There are some issues using Linux iptables, bridge interface and NAT together. See details from the blog:

http://www.woitasen.com.ar/2011/09/confusion-using-iptables-nat-and-bridge/

The summary is packets forwarded between the bridged interfaces also go through iptables, therefore potentially creating connection-tracking states before it gets to the NAT-enabled outbound interface. Then later, when the packet is routed to the NAT-enabled outbound interface, the NAT table will not be consulted anymore because the conn-track entry already exists for that packet.

The two possible solutions:

  • echo 0 > /proc/sys/net/bridge/bridge-nf-call-iptables #To disable Iptables in the bridge.
  • Raw table: This table can be used to avoid packets (connection really) to enter the NAT table: iptables -t raw -I PREROUTING -i BRIDGE -s x.x.x.x -j NOTRACK.

March 7, 2016

supervisor add new a process

after adding the process.conf file in /etc/supervisor/conf.d/, run:

supervisorctl reread
supervisorctl update

http://www.onurguzel.com/supervisord-restarting-and-reloading/

March 4, 2016

nmap test ciphers of remote server

 nmap --script ssl-enum-ciphers -p 443 your-test-site.com

February 24, 2016

dokuwiki remove register link on top page

lib/tpl/dokuwiki/tpl_header.php, search for "register" and comment out the line.

February 9, 2016

Simplifying your network with a bridge - Making an FIOs ActionTec MI424-WR a Network Bridge

http://www.hanselman.com/blog/SimplifyingYourNetworkWithABridgeMakingAnFIOsActionTecMI424WRANetworkBridge.aspx

Start your own DOCSIS lab

To setup a DOCSIS Lab you'll need:
- 1x CMTS (no it's not possible to use a Linux based PC convert into a Cable router.Ok? We close this forever or until a hardware manufacturer will sell PCIExpress Coax interfaces. BUT!!!!! If you know a manufacturer who do this, please share!!)
- 1x RG-6 2way Splitter (you have to combine US/DS RF signals into a single Coax cable, yes RF splitter can combine)
- 3x RF attenuator +20dB (you are in lab, so it's not a good idea to blow up your equipments radio)
- 1x 3Way RF splitter (optional, but if you want to test 3 CM simultaneously it's a good idea)
- 1x Return path filter (you are in LAB and have to combine the US and DS, so to clear the risk to have some RF signal harmonic on your DS, this filter is a good idea)
- 1x Linux Box (I've use Debian or use any distro of your choice and provide theses services: DHCP, TFTP, ToD, Syslog and DNS)
- 1x Switch L2 (to connect your Linux box, CMTS and Internet access. Use managable switch caused if you have to trouble shoot the L3 packets, wireshark and a port mirror will became your month employee)

Your connection desing, see: http://commons.wikimedia.org/wiki/File:HFC.jpg
You will have to replace the fiber devices by the coax/RF spliters. They do the same job's on different cable type.

Yes you will have to put money on the table and buy devices. You can found really good deal into the refurbished market but for sure it will not free.

If it's OK, you will continued with the RF plan, Cable modem DOCSIS standard, OID options, Cable modem TEK and required security, DHCP provisioning/relaying and routing.

It's really possible to do it. But always keep in mind that it's not easy, you will spend many hours without results, spend money in devices and materials but it's possible.

Source:
http://www.docsis.org/node/1686

January 23, 2016

.vimrc edti binary files in hex mode

Add the following to your ~/.vimrc file, and vim will be able to edit *.bin, *.exe, and *.o files in HEX mode:

if has ("autocmd")
" vim -b : edit binary using xxd-format!
augroup Binary
au BufReadPre  *.bin,*.exe,*.o let &binary=1
au BufReadPost * if &binary | %!xxd
au BufReadPost * so $VIMRUNTIME/syntax/xxd.vim | set filetype=xxd | endif
au BufWritePre * if &binary | %!xxd -r
au BufWritePre * endif
au BufWritePost * if &binary | %!xxd
au BufWritePost * set nomod | endif
augroup END
endif

January 14, 2016

lsyncd.conf file

settings = {
        delay        = 0.1,
        maxProcesses = 3,
        logfile      = "/tmp/lsyncd.log",
}

targetlist = {
        "192.168.5.203",
        "192.168.5.204"
}

for _, server in ipairs(targetlist) do
sync{
        default.rsyncssh,
        source="/home/me/mysyncdir",
        host=server,
        targetdir="mysyncdir"
}
end

Xbox one firewall ports

Here is what we actually need to make this work.
  protocol port direction
DNS UDP 53 outbound if you don’t have DNS services on your subnet
HTTP TCP 80 outbound
Kerberos UDP 88 inbound and outbound (yes, Xbox Live uses Kerberos for authentication.)
Xbox UDP 3074 inbound and outbound
Xbox TCP 3074 inbound and outbound
SIP UDP 5060-5061 inbound and outbound

January 13, 2016

travel agents to buy international tickets

飞翔旅游 SBP Travel 951-200-3308
909-614-4648
626-275-2811
619-209-7736
飞霖旅游 FeiLin Travel Inc 951-461-8723
951-200-0172
626-539-5608
佳友旅遊 Luckyer Travel 626-281-2568
Bravo Travel 626-571-1899
来来旅行社 Lai Lai Travel 626-286-6123
完美旅游 Perfect Trans & Travel Service 626-300-3888
800-341-7983          

December 31, 2015

php code to normalize US phone number

This is the power of regex
Source: http://stackoverflow.com/questions/4708248/formatting-phone-numbers-in-php

This is a US phone formatter that works on more versions of numbers than any of the current answers.
$numbers = explode("\n", '(111) 222-3333
((111) 222-3333
1112223333
111 222-3333
111-222-3333
(111)2223333
+11234567890
    1-8002353551
    123-456-7890   -Hello!
+1 - 1234567890 
');


foreach($numbers as $number)
{
    print preg_replace('~.*(\d{3})[^\d]{0,7}(\d{3})[^\d]{0,7}(\d{4}).*~', '($1) $2-$3', $number). "\n";
}

And here is a breakdown of the regex:
Cell: +1 999-(555 0001)

.*          zero or more of anything "Cell: +1 "
(\d{3})     three digits "999"
[^\d]{0,7}  zero or up to 7 of something not a digit "-("
(\d{3})     three digits "555"
[^\d]{0,7}  zero or up to 7 of something not a digit " "
(\d{4})     four digits "0001"
.*          zero or more of anything ")"
Updated: March 11, 2015 to use {0,7} instead of {,7}

December 15, 2015

Linux routing based on IPtables MARK

http://www.linuxhorizon.ro/iproute2.html

Backup:

This page is a small HOWTO about the advanced linux routing...

First of all let me tell you where you can find the best source of information about the advanced routing under Linux. Most of you probably know or heard about the Linux Advanced Routing & Traffic Control site. There you can see a very comprehensive source of knowledge based not only on documentation but by easy to understand examples...
Credits: Linux Advanced Routing & Traffic Control, Thea
Ok, then...
This page will show you how to set a linux box to use 2 different ISPs on the same time...

First example:
Goal: To route packets that came from 4 network to different ISPs

Let's presume that you have two ISPs. In the following examples I'll use RDS and ASTRAL (two large ISPs from my country)
For the ASCII art and lynx console browser fans I'll use this kind of chart:
                                                                   ________
                                           +-------------+        /
                                           |    ISP 1    |       /
                             +-------------+    (RDS)    +------+
                             |             | gw 10.1.1.1 |     /
                      +------+-------+     +-------------+    / 
+----------------+    |     eth1     |                       /
|                |    |              |                      |
| Local networks +----+ Linux router |                      |  Internet cloud
|                |    |              |                      |
+----------------+    |     eth2     |                       \
                      +------+-------+     +-------------+    \
                             |             |    ISP 2    |     \
                             +-------------+  (ASTRAL)   +------+
                                           | gw 10.8.8.1 |       \
                                           +-------------+        \________
We will work only on Linux router box. From the root prompter do:
echo 1 RDS >> /etc/iproute2/rt_tables
echo 2 ASTRAL >> /etc/iproute2/rt_tables
The /etc/iproute2/rt_tables content after previous commands:
#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep
1 RDS
2 ASTRAL
Now we have three routing tables as follows: RDS table, ASTRAL table and the main table...
Let's fill up every table with the defaults routes:

The next step is to have some routing rules and routes:

For the RDS table:
ip route add default via 10.1.1.1 dev eth1 table RDS
ip rule add from 10.11.11.0/24 table RDS
ip rule add from 10.12.12.0/24 table RDS 
For the ASTRAL table:
ip route add default via 10.8.8.1 dev eth2 table ASTRAL
ip rule add from 10.22.22.0/24 table ASTRAL
ip rule add from 10.33.33.0/24 table ASTRAL
To see the routing tables:
ip route show table ASTRAL
ip route show table RDS
ip route show table main  # it's the same as "route -n" but in different format...
To see the routing tables:
ip rule show   # all the rule list
ip rule show | grep ASTRAL # only for ASRAL
ip rule show | grep RDS  # only for RDS
Let me explain the above rules.
The packets that came from the 10.11.11.0/24 and 10.12.12.0/24 networks will go to the RDS routing table and then (because we have a default route) will be passed to the RDS gateway. And similar, the packets that came from the 10.22.22.0/24 and 10.33.33.0/24 network will go to the ASTRAL gateway...
What is happening with the packets that came from other networks that are not shown in the above rules? Well, they just simply go to main routing table and follow the routing rules that reside there... If you want to block them to go to internet just delete the default route from the main table... (of course, doing that your router can not longer go to interent).


Second example:
Goal: To route the packets having the destination port 22/tcp to the RDS and 80/tcp to the ASTRAL (no matter what network generates them).
This example it is almost the same as the first one except that we will use iptables to mark the packets.

Same chart...
                                                                   ________
                                           +-------------+        /
                                           |    ISP 1    |       /
                             +-------------+    (RDS)    +------+
                             |             | gw 10.1.1.1 |     /
                      +------+-------+     +-------------+    / 
+----------------+    |     eth1     |                       /
|                |    |              |                      |
| Local networks +----+ Linux router |                      |  Internet cloud
|                |    |              |                      |
+----------------+    |     eth2     |                       \
                      +------+-------+     +-------------+    \
                             |             |    ISP 2    |     \
                             +-------------+  (ASTRAL)   +------+
                                           | gw 10.8.8.1 |       \
                                           +-------------+        \________

Same /etc/iproute2/rt_tables content:
#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep
1 RDS
2 ASTRAL
Before you start check your iptables configuration. I strongly recommend to read about iptables if you are unsure about what you will doing next.
For more documentation go to iptables home page or you can download a good documentation from this site (Security & Privacy Section) or directly from here.

To mark the packets that have the 22 and 80 as destination port we will use the MANGLE table...
iptables -A PREROUTING -t mangle -i eth0 -p tcp --dport 22 -j MARK --set-mark 1
iptables -A PREROUTING -t mangle -i eth0 -p tcp --dprot 80 -j MARK --set-mark 2
For the RDS table:
ip route add default via 10.1.1.1 dev eth1 table RDS # the same like in the first example
For the ASTRAL table:
ip route add default via 10.8.8.1 dev eth2 table ASTRAL # the same like in the first example
The next step is to have some routing rules based by the marked packets:

For the RDS:
ip rule add from all fwmark 1 table RDS
For the ASTRAL:
ip rule add from all fwmark 2 table ASTRAL
You can use the same commands to see the routing tables and rule lists as in the first example.
Now you have a routing solution based by the destination port...

December 14, 2015

RE: How to receive a million packets per second

https://blog.cloudflare.com/how-to-receive-a-million-packets/

rsyslogd dynamically create log file based on msg content

This is tested on a Ubuntu 10.04 system (should work on newer Ubuntu/Debian system too)

1. Create file /etc/rsyslog.d/30test.conf, with the following content:

$template DynFile,"/tmp/test-%msg:7:18%.log"
:msg,startswith," ABCD-001122334455" ?DynFile
#:syslogtag,startswith,"test" ?DynFile
#:syslogtag,startswith,"test" /tmp/test.log

2. Open file /etc/rsyslog.conf, and make the following modification for the following line:
$FileCreateMode 0644
comment out the following lines:
#$PrivDropToUser syslog
#$PrivDropToGroup syslog

3. sudo service rsyslog restart
4. logger -t test "ABCD-001122334455sdfsfsdfsdfsdfsdfs-----------"
5. Now check file /tmp/test-*.log, and you should see file /tmp/test-001122334455.log

To Log message with a defined template
1. First define the template
      $template shortlog,"%msg:10:1000%"
2. Use the template by appending ";template-name" to the end of the output file

Notes:

a. Property msg starts with a space " ". 
b. Eventually we should try to figure out why dropPriviledge does causes issues here.

TIPS:

A good debugs tip:
1. add /etc/rsyslog.d/debug.conf
*.* /var/log/all.log;RSYSLOG_DebugFormat
#Note here ";RSYSLOG_DebugFormat" is the output template
2. restart rsyslog
3. watch the file /var/log/all.log to see all log messages with property names

Log with UNIX Timestamp
$template unixTS,"%timegenerated:::date-unixtimestamp%,%msg%\n"
:msg,contains,"[UFW " /var/log/ufw.log;unixTS

#Note here ";unixTS" is the output template

http://www.rsyslog.com/tag/use-a-template/
Also refer to the rsyslog PDF version of the manual (Chapter 1) for overview of how rsyslogd processes messages)

Syntax Check
rsyslogd -N1

===============UPDATE: New Syntax for Syslog version 7 and newer =============
rsyslog's new syntax is called "RainerScript". To generate dynamic files using output templates, generate a file in /etc/rsyslogd.conf/10-mytest.conf with the following content, and then restart service rsyslogd. The following example only logs message from the application "abc" and the message itself starts with "ABC" to a dynamic file name.

template(name="myfilename" type="string" string="/tmp/my-%programname%.log")
template(name="shortlog" type="string" string="%msg:10:$%\n")
if  $programname == 'abc' and $msg startswith " ABC"  then {
    action(type="omfile" dynaFile="myfilename" template="shortlog" )

}


=============UPDATE: More examples==================
1. variables are set using "set" and they start with "$!" in Rainer Scripts
2. variables only work inside the if block
3. Inside template the variables are surrounded by %%. e.g. "%$!devid%"
4. "stop" has replaced the "~" to discard a particular message.

module(load="omprog")
template(name="devid" type="string" string="%$!devid%")
if ($programname == 'charon') then {
    if ($msg contains "deleting IKE_SA")  then {
        set $!devid= re_extract($msg, "([A-Z0-9])+-([A-Z0-9])+.vpnclient.meetcircle.co", 0, 0, "unknown");
        #action(type="omfile" file="/var/log/delete.log" template="devid" )
        action(type="omfwd" Target="192.168.1.2" Port="15140" Protocol="tcp" template="devid" )
        #action(type="omprog" binary="/usr/bin/rsyslogpost.sh" template="devid")
    }
}

:programname,isequal,"charon" stop

December 2, 2015

dnsmasq with Ubuntu 14.04

To make it work, you may need to edit the file
/etc/default/dnsmasq.conf

and uncomment this line:
IGNORE_RESOLVCONF=yes

November 25, 2015

jquery ajax error handling

$.ajax({
    url: 'http://10.2.3.4/api/user',
    type: 'GET',
    dataType: 'json',
    success: function() { alert("Success"); },
    error: function(jqXHR, textStatus, errorThrown) {
        alert('An error occurred');
        $('#result').html('<p>status code: '+jqXHR.status+'</p><p>errorThrown: ' + errorThrown + '</p><p>jqXHR.responseText:</p><div>'+jqXHR.responseText + '</div>');
        console.log('jqXHR:');
        console.log(jqXHR);
        console.log('textStatus:');
        console.log(textStatus);
        console.log('errorThrown:');
        console.log(errorThrown);
    },
});

PHP code to analyze an the section of the 8 empty boxes below and find out how many boxes (letters in the word) are there. In this case, it should be 8.



<?php
$filename="JYkXXDylGfWH.jpg";
$tmp_img=$filename;

if(preg_match('/[.](jpg)$/', $filename)) {
    $img = imagecreatefromjpeg($tmp_img);
} else if (preg_match('/[.](gif)$/', $filename)) {
    $img = imagecreatefromgif($tmp_img);
} else if (preg_match('/[.](png)$/', $filename)) {
    $img = imagecreatefrompng($tmp_img);
}

list($width, $height) = getimagesize($tmp_img);
$y=$height/2;

$sum0=1000;
$count=0;

for ($j = 0; $j < $width; $j++) {
    $x = $j; // Get X coords

    $rgb = imagecolorat($img, $x, $y); // Get pixel color
    $r = ($rgb >> 16) & 0xFF;
    $g = ($rgb >> 8) & 0xFF;
    $b = $rgb & 0xFF;
    $sum=$r+$g+$b;
    printf("%d ",$sum);
    if ($sum0>80 && $sum<40){
        $count++;
        echo "Box $count\n";
    }
    if ($sum>80 || $sum<40){ //80 is light threshold, 40 is dard threshold
        $sum0=$sum;
    }
}

November 24, 2015

use runit to manage user space daemons

In debian/Ubuntu, install "runit".

then in /etc/service directory, create your user service directory. In this example, we use "nc" (netcat listen)

cd /etc/service; mkdir nc
now create a file called "run", with the following content:
#!/bin/sh
d=`date`;
DIR=$(dirname $(readlink -f "$0"))
name=$(basename "$DIR")
echo "$d service $name started" >> /var/log/runit.log
exec nc -l -p 8889

Only the first line and last line are must have. The mittle 4 lines are for logging purpose. 
Now "chmod +x run" 

Now nc should be running (automatically picked up by runsvdir which scans /etc/service directory for changes). list of commands:
sv status nc
sv stop nc (or sv down nc)
sv start nc (or sv up nc)
sv restart nc
sv reload nc (send HUP signal)

sv status /etc/service/* (check all service status)

touch a file "nc/down" to stop the auto-restart

create a file "nc/finish" with the following content:
#!/bin/sh
d=`date`;
DIR=$(dirname $(readlink -f "$0"))
name=$(basename "$DIR")
echo "$d service $name  stopped" >> /var/run/runit.log

This script is run every time nc exits.

Internally, 3 core executables: sv, runsv (the actual daemon monitor), and runsvdir (monitors the entire /etc/service directory)

bash get script directory

DIR=$(dirname "$(readlink -f "$0")")
echo $DIR

Openwrt iptables add NFQUEUE support

opkg install kmod-nfnetlink_3.10.49-1_ar71xx.ipk
opkg install kmod-nfnetlink-queue_3.10.49-1_ar71xx.ipk
opkg install kmod-ipt-nfqueue_3.10.49-1_ar71xx.ipk
opkg install iptables-mod-nfqueue_1.4.21-1_ar71xx.ipk
modprobe xt_NFQUEUE

modprobe nfnetlink_queue
(the last command automatically loads nfnetlink module)

Application program will need the following libraries:

libmnl_1.0.3-1_ar71xx.ipk
libnfnetlink_1.0.1-1_ar71xx.ipk

libnetfilter_queue.so.1 (libnetfilter_queue in openwrt 14.07 seems to be in the "old" package directory. You can build your own).



Then you can direct desired traffic to the user space's queue application using iptables:

 iptables -A OUTPUT -p TCP --dport 54321 -j NFQUEUE

Queue application has to be running. Otherwise, packet will stop flowing.

November 17, 2015

How to solve: automake is missing on your system

rm aclocal.m4
automake

and then do "./configure"

November 9, 2015

supervisord add new program

After adding new program in /etc/supervisord.conf, do:

sudo supervisorctl reread
sudo supervisorctl update

This will make it run

November 3, 2015

apache .htaccess pass URI to PHP

1. enable mod_rewrite : a2enmod rewrite
2. enable .htaccess by adding the following to the enabled site conf file:
        <Directory "/var/www/html">
        AllowOverride All
        </Directory>


 3. Create  .htaccess at /var/www/html with the following content
  Options +FollowSymLinks
  RewriteEngine On

  RewriteCond %{SCRIPT_FILENAME} !-d
  RewriteCond %{SCRIPT_FILENAME} !-f

  RewriteRule ^.*$ ./index.php

October 30, 2015

Use adcli to join Linux computer to a Windows Domain Controller

Setup:

Domain: domain1.ncst.com
The computer that runs Windows Server 2008 R2 and is the domain controller: WIN-HPTI079TSF6, or WIN-HPTI079TSF6.domain1.ncst.com
IP address of the domain controller: 192.168.5.206

Linux computer name: git, full name with domain: git.domain1.ncst.com
Linux computer IP address: 192.168.5.204


1. Set up Linux /etc/resolv.conf to point it to the Domain Controller which should also be a DNS server

  nameserver 192.168.5.206
  nameserver 4.2.2.1

2. (Not needed anymore since Step 1's Name server would resolve this) 
Set up Linux /etc/hosts file so that the domain controller name resolves:

  192.168.5.206 win-hpti079tsf6.domain1.ncst.com

3.Set up your krb5.conf 

$ cat /etc/krb5.conf
[libdefaults]
        default_realm = DOMAIN1.NCST.COM
        kdc_timesync = 1
        ccache_type = 4
[realms]
        DOMAIN1.NCST.COM = {
                kdc = 192.168.5.206
                admin_server = 192.168.5.206
        }

4. (Not needed)
On the domain controller DNS server, add DNS A record for "git.domain1.ncst.com"

5. Finally, use the adcli command to join:
./adcli join -v --login-user=Administrator -H git.domain1.ncst.com -N GIT -D domain1.ncst.com  -R DOMAIN1.NCST.COM

 --show-details   --show-password

The result:
* Using fully qualified name: git.domain1.ncst.com
 * Using domain name: domain1.ncst.com
 * Using computer account name: GIT
 * Using domain realm: domain1.ncst.com
 * Discovering domain controllers: _ldap._tcp.domain1.ncst.com
 * Sending netlogon pings to domain controller: cldap://192.168.5.206
 * Received NetLogon info from: WIN-HPTI079TSF6.domain1.ncst.com
 * Wrote out krb5.conf snippet to /tmp/adcli-krb5-zKaph4/krb5.d/adcli-krb5-conf-FxUjvg                                                                             
 Password for Administrator@DOMAIN1.NCST.COM:
 * Authenticated as user: Administrator@DOMAIN1.NCST.COM
 * Looked up short domain name: DOMAIN1
 * Using fully qualified name: git.domain1.ncst.com
 * Using domain name: domain1.ncst.com
 * Using computer account name: GIT
 * Using domain realm: domain1.ncst.com
 * Enrolling computer name: GIT
 * Generated 120 character computer password
 * Using keytab: FILE:/etc/krb5.keytab                                             
 * Using fully qualified name: git.domain1.ncst.com
 * Using domain name: domain1.ncst.com
 * Using computer account name: GIT
 * Using domain realm: domain1.ncst.com
 * Looked up short domain name: DOMAIN1
 * Computer account for GIT$ does not exist
 * Found well known computer container at: CN=Computers,DC=domain1,DC=ncst,DC=com
 * Calculated computer account: CN=GIT,CN=Computers,DC=domain1,DC=ncst,DC=com
 * Created computer account: CN=GIT,CN=Computers,DC=domain1,DC=ncst,DC=com
 * Set computer password                                                           
 * Retrieved kvno '2' for computer account in directory: CN=GIT,CN=Computers,DC=domain1,DC=ncst,DC=com
 * Modifying computer account: dNSHostName
 * Modifying computer account: userAccountControl
 * Modifying computer account: operatingSystem, operatingSystemVersion, operatingSystemServicePack
 * Modifying computer account: userPrincipalName
 * Discovered which keytab salt to use
 * Added the entries to the keytab: GIT$@DOMAIN1.NCST.COM: FILE:/etc/krb5.keytab
 * Added the entries to the keytab: host/GIT@DOMAIN1.NCST.COM: FILE:/etc/krb5.keytab
 * Added the entries to the keytab: host/git.domain1.ncst.com@DOMAIN1.NCST.COM: FILE:/etc/krb5.keytab
 * Added the entries to the keytab: RestrictedKrbHost/GIT@DOMAIN1.NCST.COM: FILE:/etc/krb5.keytab                                                              

 * Added the entries to the keytab: RestrictedKrbHost/git.domain1.ncst.com@DOMAIN1.NCST.COM: FILE:/etc/krb5.keytab


** You can also add  --show-details   --show-password to the command to show the machine password

October 26, 2015

The 3 Records you must know for good email delivery

The 3 Records you must know for good email delivery are:
  • Reverse DNS (PTR)
  • SPF (Sender Policy Framework)
  • DKIM (DomainKeys Identified Mail)
These are the 3 core records you must have correct for sending email.   Of course, you need an MX record if you want to receive email, but that’s another topic.


https://www.rackaid.com/blog/email-dns-records/

SPF wizards