Übersicht
Stichwortsuche
History
Versionen
Kategorien
Alle Artikel
SuSE Linux: Versionen bis einschließlich 6.2
Jochen Roedenbeck (roe@spl-spindel.de) bietet folgende Lösung an:
/sbin/reject-masq --insertIn crontab (als root):
4,14,24,34,44,54 * * * * /sbin/reject-masq --deleteDer Aufruf in /etc/ppp/ip-down erzeugt die Firewall-Eintraege, der Aufruf ueber cron besorgt das Loeschen. Das Programm kann jederzeit mit "reject-masq -l" aufgerufen werden, um die gespeicherten Verbindungen anzuzeigen.
/sbin/reject-masq : Programmdatei /var/run/MASQ.* : Speicherung der Firewall-Eintraege /proc/net/ip_masquerade : Masquerading-Verbindungen
Manche Programme schlieszen eine TCP-Verbindung nicht sofort, wenn die Daten uebertragen sind, sondern halten sie noch einige Zeit ge- oeffnet, ohne weitere Daten zu uebertragen. In der Zeit beendet das ISDN-System dann die Telefonverbindung. Wenn danach die TCP-Verbindung geschlossen wird, wird noch ein IP-Paket verschickt, um die Gegen- seite vom Verbindungsabbau zu informieren. Dabei wird die Telefonverbindung dann wieder aufgebaut und das soll das Programm verhindern. Auszerdem kann die Gegenseite dieses IP-Paket auch gar nicht der noch offenen TCP-Verbindung zuordnen, da es ja mit einer anderen (neuen) Absender-IP-Adresse kommt.
Beobachtet habe ich das Problem, wenn mit mit Netscape 3.01 unter Linux auf Web-Seiten zugreift. Beim Beenden des Netscape-Programms habe ich immer einen erneuten Verbindungsaufbau bekommen. netstat zeigt, dass die http-Verbindungen nach dem Einlesen der Seite nicht sofort geschlossen werden, sondern erst nach einigen Minuten.
/***************************************************************************/ /* Reject old connections after shutting down ISDN link */ /* Copyright (C) Jochen Roedenbeck 1998 */ /***************************************************************************/ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ #define VERSION "0.01" /* for testing (/sbin/ipfwadm will not be called) */ //#define DEBUG /* If dynamic IP address allocation is used to connect the Internet all connections become invalid when the ISDN link is shut down. Nevertheless data for these old connections can be sent. This program installs firewall rules to reject these data and to prevent the ISDN system from calling out for a dead connection. usage: a) reject-masq --insert /proc/net/ip_masquerade is read. For each line in this file a forwarding firewall rule is installed to reject all packets for the connection. A file /var/run/MASQ.* is written containing the options for deleting the installed firewall rules. This command should be used in /etc/ppp/ip-down. b) reject-masq --delete [time-out value] /var/run/ is scanned for MASQ.* files. If creation time of the file is more than "time-out value" seconds ago the firewall entries listed in the file are deleted by calling /sbin/ipfwadm. The file is deleted, too. If no time-out value is specified 3600s (1h) is used. This command should be called periodically by a crontab entry. c) reject-masq --deleteall like b), but delete all firewall entries regardless of time-out value d) reject-masq -l list /proc/net/ip_masquerade and /var/run/MASQ.* */ #include <stdio.h> #include <unistd.h> #include <string.h> #include <ctype.h> #include <time.h> #include <netinet/in.h> #include <arpa/inet.h> #include <dirent.h> #include <sys/stat.h> #include <sys/syslog.h> /* command to install firewall rules */ #define FN_IPFWADM "/sbin/ipfwadm" #ifndef DEBUG #define FN_IP_MASQ "/proc/net/ip_masquerade" #define PTH_DEL_SCR "/var/run" #else #define FN_IP_MASQ "./ip_masq" #define PTH_DEL_SCR "." #endif #define REJECT_TIME 3600 typedef unsigned short in_port; struct t_conn { struct in_addr fromIP; in_port fromPort; struct in_addr toIP; in_port toPort; char protocol[4]; }; char fn_masq[]="/MASQ."; int next_Port(in_port *erg,char **_x) { char *x,*x1,s[16]; x=*_x; *erg=0; while (*x==' '||*x=='\t') x++; x1=x; while (isxdigit(*x1)) x1++; if (x1-x<sizeof(s)) { memcpy(s,x,x1-x); s[x1-x]='\0'; *erg=htons(strtoul(s,x,16)); } *_x=x1; return *erg!=0; } int next_InAddr(struct in_addr *erg,char **_x) { char *x,*x1,s[16]; x=*_x; erg->s_addr=INADDR_NONE; while (*x==' '||*x=='\t') x++; x1=x; while (isxdigit(*x1)) x1++; if (x1-x<sizeof(s)) { memcpy(s,x,x1-x); s[x1-x]='\0'; erg->s_addr=htonl(strtoul(s,x,16)); } *_x=x1; return erg->s_addr!=INADDR_NONE; } /* read line of /proc/net/ip_masquerade and convert into struct conn */ int convFwrdLine(struct t_conn *conn,char *x) { char *x1; memset(conn,0,sizeof(struct t_conn)); x1=x; while (isalpha(*x1)) x1++; memcpy(conn->protocol,x,sizeof(conn->protocol)); conn->protocol[x1-x>=sizeof(conn->protocol)? (sizeof(conn->protocol)-1):(x1-x)]='\0'; x=x1; next_InAddr(&conn->fromIP,&x); if (*x==':') { x++; next_Port(&conn->fromPort,&x); if (*x==' ') { next_InAddr(&conn->toIP,&x); if (*x==':') { x++; next_Port(&conn->toPort,&x); return 0; } } } return EOF; } /* convert struct conn into parameters for /sbin/ipfwadm command */ /* char *s - string to write */ /* int cmd - if 1, string starts with "/sbin/ipfwadm" */ /* int del - make command for inserting (0) or deleting (1) */ /* struct t_conn *conn - IP addresses and ports */ int makeIPFWcmd(char *s,int cmd,int del,struct t_conn *conn) { char fromIP[256],toIP[256],prot[sizeof(conn->protocol)],*p; strcpy(fromIP,inet_ntoa(conn->fromIP)); strcpy(toIP,inet_ntoa(conn->toIP)); strcpy(prot,conn->protocol); for (p=prot;p<prot+sizeof(prot);p++) *p=tolower(*p); return sprintf(s,"%s -F -%c reject -P %s -S %s/32 %u -D %s/32 %u", cmd?(FN_IPFWADM):"",del?'d':'i',prot, fromIP,ntohs(conn->fromPort), toIP,ntohs(conn->toPort)); } /* convert struct conn into parameters for /sbin/ipfwadm command and */ /* write command to file f */ int listLineIPFW(FILE *f,struct t_conn *conn,int start) { if (start) { return 0; } else { char s[512]; makeIPFWcmd(s,1,0,conn); fprintf(f,"%s\n",s); makeIPFWcmd(s,1,1,conn); fprintf(f,"%s\n",s); return 0; } } /* convert struct conn into parameters for /sbin/ipfwadm command, call */ /* "/sbin/ipfwadm -F -i reject ..." and write " -F -d reject ..." to */ /* file f */ int insertRule(FILE *f,struct t_conn *conn,int start) { if (start) { return 0; } else { char s[512]; makeIPFWcmd(s,1,0,conn); #ifndef DEBUG system(s); #else fprintf(stderr,"%s\n",s); #endif makeIPFWcmd(s,0,1,conn); fprintf(f,"%s\n",s); return 0; } } /* convert struct conn to ascii and write to a file */ int listLine(FILE *f,struct t_conn *conn,int start) { if (start) { return fprintf(f,"Prc From To\n"); } else { char fromIP[256],toIP[256]; strcpy(fromIP,inet_ntoa(conn->fromIP)); sprintf(fromIP+strlen(fromIP),":%u",ntohs(conn->fromPort)); strcpy(toIP,inet_ntoa(conn->toIP)); sprintf(toIP+strlen(toIP),":%u",ntohs(conn->toPort)); return fprintf(f,"%-3s %-22s -> %-22s\n",conn->protocol,fromIP,toIP); } } /* scan /proc/net/ip_masquerade and call _listLine() for each line of the */ /* file */ int list(FILE *para,int (*_listLine)(FILE*,struct t_conn*,int)) { FILE *fi; char s[512]; struct t_conn conn; int err; err=0; if ((fi=fopen(FN_IP_MASQ,"r"))!=NULL) { fgets(s,sizeof(s),fi); if (_listLine(para,NULL,1)!=EOF) { while (fgets(s,sizeof(s),fi)!=NULL) { if (convFwrdLine(&conn,s)) { syslog(LOG_ERR,"converting error: %s",s); err=EOF; break; } if (_listLine(para,&conn,0)==EOF) { err=EOF; break; } } } else err=EOF; fclose(fi); } return err; } /* scan /proc/net/ip_masquerade, call /sbin/ipfwadm for each line */ int insertF() { FILE *f; char fn[256]; int rtn; rtn=EOF; strcpy(fn,PTH_DEL_SCR); strcat(fn,fn_masq); sprintf(fn+strlen(fn),"%lX",time(NULL)); if ((f=fopen(fn,"a"))!=NULL) { rtn=list(f,insertRule); fclose(f); } return rtn; } /* scan PTH_DELSCR for files MASQ.* */ int deleteF(unsigned long reject_time,int show) { DIR *f; struct dirent *dent; char fn[256]; struct stat stt; time_t tm; unsigned long waittime; time(&tm); #ifdef DEBUG printf("time()=%lu reject_time=%lus\n",tm,reject_time); #endif if ((f=opendir(PTH_DEL_SCR))!=NULL) { while ((dent=readdir(f))!=NULL) { if (memcmp(dent->d_name,fn_masq+1,4)==0) { strcpy(fn,PTH_DEL_SCR); strcat(fn,"/"); strcat(fn,dent->d_name); stat(fn,&stt); waittime=tm-stt.st_ctime; #ifdef DEBUG printf("%s %lu %lus %s\n",dent->d_name,stt.st_ctime, waittime,waittime>reject_time?"DEL":"WAIT"); #endif if (waittime>reject_time||show) { FILE *fi; char cmd[256],*p; if ((fi=fopen(fn,"r"))!=NULL) { while (fgets(cmd+strlen(FN_IPFWADM),sizeof(cmd)-strlen(FN_IPFWADM),fi)!=NULL) { strcpy(cmd,FN_IPFWADM); cmd[strlen(FN_IPFWADM)]=' '; if ((p=strchr(cmd,'\n'))!=NULL) *p='\0'; if (show) { printf("%s(%4lus) %s\n", waittime>reject_time?"DEL ":"WAIT", waittime, cmd+strlen(FN_IPFWADM)+1); } else if (memcmp(cmd+strlen(FN_IPFWADM)," -F -d reject",13)==0) { #ifndef DEBUG system(cmd); #else printf("%s\n",cmd); #endif } else { #ifndef DEBUG syslog(LOG_WARNING,"INVALID: %s",cmd); #else printf("INVALID: %s\n",cmd); #endif } } fclose(fi); if (!show) unlink(fn); } } } } closedir(f); } return 0; } int main(int argc,char **argv) { int rtn; rtn=1; openlog(argv[0],LOG_PID,LOG_USER); umask(077); if (argc>1) { if (strcmp(argv[1],"-l")==0) { /* list */ list(stdout,listLine); deleteF(REJECT_TIME,1); rtn=0; } else if (strcmp(argv[1],"--insert")==0) { /* scan /proc/net/ip_masquerade and insert new firewall rules */ rtn=insertF()==EOF?1:0; } else if (strcmp(argv[1],"--delete")==0) { /* delete timed out firewall rules */ unsigned long timeout; char *ende; timeout=REJECT_TIME; if (argc>2) { timeout=strtoul(argv[2],&ende,10); if (*ende=='m') timeout*=60; else if (*ende=='h') timeout*=3600; } if (timeout==0||timeout>24L*3600L) { fprintf(stderr,"invalid time-out: %lus\n",timeout); return 1; } rtn=deleteF(timeout,0)==EOF?1:0; } else if (strcmp(argv[1],"--deleteall")==0) { /* delete all */ rtn=deleteF(0,0)==EOF?1:0; } else { list(stdout,listLineIPFW); rtn=0; } } else { printf("%s [-l] [--insert] [--delete [time-out]] [--deleteall] [-s]\n", argv[0]); } closelog(); return rtn; }
Siehe auch:
Stichwörter: ISDN, DYNAMISCH, VERBINDUNG, STÄNDIG, MASQUERADE, IPPPD
Kategorien:
ISDN
Übersicht
Stichwortsuche
History
Versionen
Kategorien
Alle Artikel