How to use iptables to connect proxy server
Solution 1
Try this rule:
iptables -t nat -A PREROUTING -i eth0 -s ! 192.168.0.2 -p tcp --dport 80 -j DNAT --to 192.168.0.2:3128
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/24 -d 192.168.0.2 -j SNAT --to 192.168.0.1
iptables -A FORWARD -s 192.168.0.0/24 -d 192.168.0.2 -i eth0 -o eth0 -p tcp --dport 3128 -j ACCEPT
where:
192.168.0.2 - proxy server IP (Squid, etc);
192.168.0.1 - router IP (where started iptables);
192.168.0.0/24 - your local network
I could be wrong, check carefully.
Solution 2
Without having tested it I think the solution @ymn is valid for HTTP, but I don't think you can get around specifying an equivalent line for HTTPS - indeed any such solution should throw up certificate errors etc because you are, in-effect, doing a man-in-the-middle attack on your own network.
(You may be able to get round this - to some degree - but its not a good idea as you are stripping the security SSL gives. Have a look at sslstrip - http://www.thoughtcrime.org/software/sslstrip/)
Maybe a better middle ground might be to try doing proxy autoconfiguration (WPAD with DHCP) - http://wiki.squid-cache.org/SquidFaq/ConfiguringBrowsers#Fully_Automatically_Configuring_Browsers_for_WPAD
Related videos on Youtube
es483
Updated on September 18, 2022Comments
-
es483 over 1 year
While writing a program using RAW and
SOCK_DRAM
UDP sockets, I noticed that the Ethernet Maximum Transmission Unit is always representing a limit to the data I can send without incurring into fragmentation, even if the socket is strictly bound to a wireless interface (usingbind()
) and the packets are always transmitted on the air using Wi-Fi (802.11), without any wired network segment in between.I knew the 802.11 MTU to be 2346 B (is it correct?), which is larger than 1500 B. But if I try to transmit more than the Ethernet MTU size (1500 B), I get fragmentation when using UDP sockets and a "message too big" error (
errno 90
,EMSGSIZE
) when usingsendto()
on RAW sockets.Is this due to the fact that, from the point of view of the user applications, 802.11 packets are seen as 802.3 packets which are then converted and managed inside the kernel and hardware devices? Why is this limit applying even if I could transmit larger frames with "Wi-Fi"?
Edit: sample code to reproduce the problem for RAW sockets
Here is a sample code, extracted from the original one, that you can compile with
gcc
and use to reproduce the problem I described before.When using RAW sockets a message over 1500 B is explicitely rejected, setting
errno
, even when the socket is bound to a wireless interface.Here is the code:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <linux/wireless.h> #include <sys/socket.h> #include <linux/if_packet.h> #include <net/ethernet.h> #include <arpa/inet.h> #include <string.h> #include <sys/ioctl.h> #define DEVNAME "wlp2s0" #define DESTINATIONMAC_INITIALIZER {0x9C,0xD2,0x1E,0x20,0x91,0xE5} #define SIZEOK 1500 #define SIZEWRONG 1501 int main (int argc, char **argv) { // wlanLookup() variables, for interface name, source MAC address and return value char devname[]=DEVNAME; int ifindex; int descriptor; // Socket descriptor struct sockaddr_ll addrll; // sockaddr_ll address structure struct ifreq wifireq; struct ether_header etherHeader; unsigned char bufferok[SIZEOK]; unsigned char bufferwrong[SIZEWRONG]; unsigned char *packetok=NULL; unsigned char *packetwrong=NULL; // Source and destination MAC addresses unsigned char macsrc[6]; unsigned char macdst[6]=DESTINATIONMAC_INITIALIZER; // Size variables int sentbytes; size_t sizeok_final=sizeof(struct ether_header)+SIZEOK; // Size of the ok buffer + size of struct ether_header size_t sizewrong_final=sizeof(struct ether_header)+SIZEWRONG; // Size of the ok buffer + size of struct ether_header if(SIZEWRONG<SIZEOK) { fprintf(stderr,"Error: in this sample code, SIZEWRONG (%d) must be >= than SIZEOK (%d)\n",SIZEWRONG,SIZEOK); exit(EXIT_FAILURE); } descriptor=socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL)); if(descriptor==-1) { perror("socket() error"); exit(EXIT_FAILURE); } // Get interface index of the interface strncpy(wifireq.ifr_name,devname,IFNAMSIZ); if(ioctl(descriptor,SIOCGIFINDEX,&wifireq)!=-1) { ifindex=wifireq.ifr_ifindex; } else { perror("ioctl() error"); close(descriptor); exit(EXIT_FAILURE); } fprintf(stdout,"Using interface: %s (index: %x)\n",DEVNAME,ifindex); // Prepare sockaddr_ll structure memset(&addrll,0,sizeof(addrll)); addrll.sll_ifindex=ifindex; addrll.sll_family=AF_PACKET; addrll.sll_protocol=htons(ETH_P_ALL); // Bind to the wireless interface if(bind(descriptor,(struct sockaddr *) &addrll,sizeof(addrll))<0) { perror("Cannot bind to interface: bind() error"); close(descriptor); exit(EXIT_FAILURE); } fprintf(stdout,"Bound to interface: %s (index: %x)\n",DEVNAME,ifindex); // Populate both buffers with some data for(int i=0;i<SIZEWRONG;i++) { if(i<SIZEOK) { bufferok[i]=(unsigned char) (i & 15); // Fill each byte with a cyclic sequence 0x00, 0x01, 0x02, ... 0x0F, 0x00, 0x01, ... } bufferwrong[i]=(unsigned char) (i & 15); } // Get source MAC address strncpy(wifireq.ifr_name,devname,IFNAMSIZ); if(ioctl(descriptor,SIOCGIFHWADDR,&wifireq)!=-1) { memcpy(macsrc,wifireq.ifr_hwaddr.sa_data,6); } else { perror("Cannot get source MAC address: ioctl() error"); close(descriptor); } fprintf(stdout,"Source MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",macsrc[0],macsrc[1],macsrc[2],macsrc[3],macsrc[4],macsrc[5]); fprintf(stdout,"Destination MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",macdst[0],macdst[1],macdst[2],macdst[3],macdst[4],macdst[5]); // Fill struct ether_header memcpy(etherHeader.ether_dhost,macdst,ETHER_ADDR_LEN); memcpy(etherHeader.ether_shost,macsrc,ETHER_ADDR_LEN); // Using local experimental ethertype for the sake of this sample code, but the effect is the same for any other EtherType etherHeader.ether_type=htons(0x88B5); packetok=malloc(sizeok_final*sizeof(unsigned char)); if(!packetok) { perror("malloc() error"); close(descriptor); exit(EXIT_FAILURE); } packetwrong=malloc(sizewrong_final*sizeof(unsigned char)); if(!packetwrong) { perror("malloc() error"); free(packetok); close(descriptor); exit(EXIT_FAILURE); } // Generate the complete packet buffers // Packet OK memcpy(packetok,ðerHeader,sizeof(struct ether_header)); memcpy(packetok+sizeof(struct ether_header),bufferok,sizeok_final); // Packet WRONG memcpy(packetwrong,ðerHeader,sizeof(struct ether_header)); memcpy(packetwrong+sizeof(struct ether_header),bufferwrong,sizewrong_final); sentbytes=sendto(descriptor,packetok,sizeok_final,0,(struct sockaddr *)&addrll,sizeof(struct sockaddr_ll)); perror("Packet OK errors (if any)"); fprintf(stdout,"Packet OK: sent %d bytes.\n",sentbytes); sentbytes=sendto(descriptor,packetwrong,sizewrong_final,0,(struct sockaddr *)&addrll,sizeof(struct sockaddr_ll)); perror("Packet WRONG errors (if any)"); fprintf(stdout,"Packet WRONG: sent %d bytes.\n",sentbytes); close(descriptor); return 0; }
Before compiling, you should set
DEVNAME
to the name of the interface the sample program should bind to andDESTINATIONMAC_INITIALIZER
to the destination device you want to try to send packets to.I actually got this output (after running the program with
sudo
), showing how a packet over 1500 B is rejected:Using interface: wlp2s0 (index: 3) Bound to interface: wlp2s0 (index: 3) Source MAC address: 00:16:ea:4a:bd:7e Destination MAC address: 9c:d2:1e:20:91:e5 Packet OK errors (if any): Success Packet OK: sent 1514 bytes. Packet WRONG errors (if any): Message too long Packet WRONG: sent -1 bytes.
The "ok" packets, when launching the sample program for three times, were correctly received by the destination device, while all the "wrong" ones were not:
Thank you very much in advance.
-
735Tesla about 5 yearsI used to maintain software that did a lot of 802.11 frame generation/injection on Linux and never ran into that issue. Could I see the relevant code?
-
es483 about 5 years@735Tesla Of course! I just updated the original question with a sample code, extracted from the original one, that you can compile with
gcc
and that it should reproduce the problem for raw sockets. For what concernsSOCK_DGRAM
, instead, the packet is always sent, but it gets fragmented when the size exceeds 1500 B (it can be seen not through a direct error, but for instance when using Wireshark). Thank you very much in advance.
-
-
siyuan over 11 yearsThere is already a squid server on my router now.
-
siyuan over 11 yearsThank you! There is already a squid server on my router now. Suppose my company's proxy is proxy.com:85, we setup a squid 192.168.0.5:3128. Now, we can access Internet by setting proxy as 192.168.0.5:3128 or proxy.com:85. What I want is to access Internet without setting proxy, because some program can't set proxy, such as some online update.