Stuart Henderson wrote:
On 2009-02-24, Gregory Edigarov <g...@bestnet.kharkov.ua> wrote:
Is this a bug of feature?
the test case:

# ifconfig lo1 192.168.0.1 up

# ping 192.168.0.1
64 bytes from 192.168.0.1: icmp_seq=0 ttl=255 time=0.200 ms
64 bytes from 192.168.0.1: icmp_seq=1 ttl=255 time=0.111 ms
64 bytes from 192.168.0.1: icmp_seq=2 ttl=255 time=0.110 ms
64 bytes from 192.168.0.1: icmp_seq=3 ttl=255 time=0.111 ms
64 bytes from 192.168.0.1: icmp_seq=4 ttl=255 time=0.109 ms

this should work. how does your routing table look?

Ok, so here is more on the test case... the initial idea was to shape some traffic destined to services settling on the host by redirecting it to lo1, then pointing services to listen on
the IP of lo1.

*************************************************************************
# ifconfig lo1
lo1: flags=8149<UP,LOOPBACK,RUNNING,PROMISC,MULTICAST> mtu 33204
       groups: lo
       inet 192.168.0.1 netmask 0xffffff00

# route -n show
Routing tables

Internet:
Destination Gateway Flags Refs Use Mtu Prio Iface
default            80.92.224.1        UGS        8   161457     -    48 rl0
80.92.224.0/27     link#1             UC         3        0     -    48 rl0
80.92.224.1        00:04:4d:39:59:20  UHLc       1        0     -    48 rl0
80.92.224.10       00:50:8d:61:96:65  UHLc       0       15     -    48 rl0
80.92.224.20       00:07:e9:05:1e:ec  UHLc       0      103     -    48 rl0
127.0.0.1          127.0.0.1          UH         0        0 33204    48 lo0
192.168.0.1        192.168.0.1        UH         0      376 33204    48 lo1
*************************************************************
# cat /etc/pf.conf

table <badhosts> persist
table <sshdeny> persist
table <counters> persist
table <spamd> persist
table <spamd-white> persist


set ruleset-optimization none

scrub all

#altq on lo1 cbq bandwidth 5Mb queue { std, ext}
#queue std bandwidth 10% cbq(default)
#queue ext bandwidth 90% cbq

nat on rl0 from 192.168.0.1 to any -> (rl0)
rdr on rl0 proto tcp from any to (rl0) port 1234 -> (lo1)

block log all
pass out on rl0
pass in on rl0 proto tcp from any to (rl0) port ftp keep state
pass in on rl0 proto tcp from any to (rl0) port ftp-data keep state
pass in on rl0 proto tcp from any to (rl0) port ssh keep state \
(max-src-conn 3, max-src-conn-rate 1/60, overload <sshdeny> flush global)
pass in on rl0 proto tcp from  194.6.232.83 to (rl0) port ssh keep state
pass in on rl0 proto tcp from any to (rl0) port smtp keep state
pass in on rl0 proto tcp from any to (rl0) port 4662 keep state
pass in on rl0 proto tcp from any to 192.168.0.1 port 1234 keep state

pass in on rl0 proto udp from any to (rl0) port 4665 keep state
pass in on rl0 proto udp from any to (rl0) port 4672 keep state
pass in on rl0 inet proto icmp from any to (rl0) icmp-type echoreq
block drop in log on rl0 from <sshdeny> to (rl0)

pass on rl0 from <counters> to any
pass on rl0 from   any to <counters>

pass on lo0
pass on lo1
#pass on lo1 queue std

******************************************************************

on this host we run 'nc -l 1234', or this simple C test, just to be sure we are listening on right socket:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#define TRUE 1

/*
* This program creates a socket and then begins an infinite loop. Each time
* through the loop it accepts a connection and prints out messages from it.
* When the connection breaks, or a termination message comes through, the
* program accepts a new connection.
*/

main()
{
       int sock, length;
       struct sockaddr_in server;
       int msgsock;
       char buf[1024];
       int rval;
       int i;

       /* Create socket */
       sock = socket(AF_INET, SOCK_STREAM, 0);
       if (sock < 0) {
               perror("opening stream socket");
               exit(1);
       }
       /* Name socket using wildcards */
       server.sin_family = AF_INET;
       server.sin_addr.s_addr = inet_addr("192.168.0.1");
       server.sin_port = htons (1234);
       if (bind(sock, &server, sizeof(server))) {
               perror("binding stream socket");
               exit(1);
       }
       /* Find out assigned port number and print it out */
       length = sizeof(server);
       if (getsockname(sock, &server, &length)) {
               perror("getting socket name");
               exit(1);
       }
       printf("Socket has port #%d\en", ntohs(server.sin_port));

       /* Start accepting connections */
       listen(sock, 5);
       do {
               msgsock = accept(sock, 0, 0);
               if (msgsock == -1)
                       perror("accept");
               else do {
                       bzero(buf, sizeof(buf));
                       if ((rval = read(msgsock, buf, 1024)) < 0)
                               perror("reading stream message");
                       i = 0;
                       if (rval == 0)
                               printf("Ending connection\en");
                       else
                               printf("-->%s\en", buf);
               } while (rval != 0);
               close(msgsock);
       } while (TRUE);
       /*
        * Since this program has an infinite loop, the socket "sock" is
        * never explicitly closed.  However, all sockets will be closed
        * automatically when a process is killed or terminates normally.
        */
}


on some other host we run 'telnet IP  1234', and type something in.
again, running tcpdump -i lo1 shows us nothing relevant.
BUT(!) if I  redirect to lo0, then tcpdump -i lo0 shows packets correctly.

The same thing happen when altq bound to lo1, the counters show all zeros.

--
With best regards,
        Gregory Edigarov

Reply via email to