Зачем Перл?
Это можно сделать на AWK.
Вы же все равно используете AWK

Скорость возрастет в разы.
Если интересно, могу накидать.
Да, похоже я изрядно лоханулся.kpp писал(а):2 lazhu
Зачем Перл?
Это можно сделать на AWK.
Вы же все равно используете AWK
Скорость возрастет в разы.
Если интересно, могу накидать.
Код: Выделить всё
values=`awk -v q="'" 'BEGIN {ORS=",";OFS=","}{print "(FROM_UNIXTIME("$8")",q$1q,q$2q,q$3q,q$4q,q$5q,q$6q,q$7q")"}' ${log} | sed 's/,$/;/'`
echo 'INSERT INTO `'${iface}'` (`date`,`src_ip`,`src_port`,`dst_ip`,`dst_port`,`protocol`,`packets`,`bytes`) VALUES' ${values} | ${sql}
Код: Выделить всё
awk -v q="'" 'BEGIN {ORS=",";OFS=","}{print "(FROM_UNIXTIME("$8")",q$1q,q$2q,q$3q,q$4q,q$5q,q$6q,q$7q")"}' ${log} | sed 's/,$/;/'
Код: Выделить всё
fmt="(FROM_UNIXTIME(%s),'%s','%s','%s','%s','%s','%s','%s');"
awk -v fmt=$fmt '{printf fmt, $8,$1,$2,$3,$4,$5,$6,$7}' ${log}
Нет, цикл убран. AWK выводит весь файл в переменную, которая затем подставляется в sql-запрос.kpp писал(а):И это еще не вся оптимизация - ведь, насколько я понял, цикл while у вас так и остался...
Да, логично, только строки в формуле VALUE должны разделяться запятыми, точка с запятой ставится в конце запроса. Поэтому костыль с седом.kpp писал(а):Уже лучше
А как Вам замена:На:Код: Выделить всё
awk -v q="'" 'BEGIN {ORS=",";OFS=","}{print "(FROM_UNIXTIME("$8")",q$1q,q$2q,q$3q,q$4q,q$5q,q$6q,q$7q")"}' ${log} | sed 's/,$/;/'
Код: Выделить всё
fmt="(FROM_UNIXTIME(%s),'%s','%s','%s','%s','%s','%s','%s');" awk -v fmt=$fmt '{printf fmt, $8,$1,$2,$3,$4,$5,$6,$7}' ${log}
Попробуйте мой вариант.lazhu писал(а): ...
Да, логично, только строки в формуле VALUE должны разделяться запятыми, точка с запятой ставится в конце запроса. Поэтому костыль с седом.
Тогда придется в awk делать цикл для строк <NR и отдельно последнюю строку. Писанины точно будет больше, а выигрыш в производительности практически нулевой. Хотя и без костылейkpp писал(а):Попробуйте мой вариант.lazhu писал(а): ...
Да, логично, только строки в формуле VALUE должны разделяться запятыми, точка с запятой ставится в конце запроса. Поэтому костыль с седом.
Костыль с седом не нужен, разделители могут быть любые, также как и символы обрамления значений полей.
Цикла нет, просто все строки выводятся с запятой, а сед меняет последнюю на точку с запятой.kpp писал(а):Гм.. значит цикл какой-то все таки есть?
Покажите весь скрипт с последними изменениями.
Код: Выделить всё
#!/bin/sh
cmd="/usr/local/sbin/ipacctctl"
iface=$1
log="/var/log/ipacct/ng_ipacct.log"
ip=
user=
passwd=
db=
cols='`date`,`src_ip`,`src_port`,`dst_ip`,`dst_port`,`protocol`,`packets`,`bytes`'
sql="/usr/local/bin/mysql --user=${user} --password=${passwd} --database=${db}"
if [ "$2" = "ext" ]; then
${cmd} -i ${iface}_ip_acct:${iface} checkpoint
else
${cmd} -o ${iface}_ip_acct:${iface} checkpoint
fi
${cmd} ${iface}_ip_acct:${iface} show >> ${log}
${cmd} ${iface}_ip_acct:${iface} clear
sed -i '' "/${ip}/d" ${log}
values=`awk -v q="'" 'BEGIN {ORS=",";OFS=","}{print "(FROM_UNIXTIME("$8")",q$1q,q$2q,q$3q,q$4q,q$5q,q$6q,q$7q")"}' ${log} | sed 's/,$/;/'`
echo 'INSERT INTO `'${iface}'` ('${cols}') VALUES' ${values} | ${sql}
rm ${log}
Код: Выделить всё
fmt="(FROM_UNIXTIME(%s),'%s','%s','%s','%s','%s','%s','%s')"
awk -v fmt=$fmt '{if(s!="")print s","; s=sprintf(fmt,$8,$1,$2,$3,$4,$5,$6,$7)} END{print s";"}' ${log}
Код: Выделить всё
fmt="(FROM_UNIXTIME(%s),'%s','%s','%s','%s','%s','%s','%s')"
awk -v fmt=$fmt -v ip="$ip" '$0 !~ ip{if(s!=""){print s","; s="";}; s=sprintf(fmt,$8,$1,$2,$3,$4,$5,$6,$7)} END{if(s!="")print s";"}' ${log}
Код: Выделить всё
sed -i '' "/${ip}/d" ${log}
kpp писал(а):Тогда так:Код: Выделить всё
fmt="(FROM_UNIXTIME(%s),'%s','%s','%s','%s','%s','%s','%s')" awk -v fmt=$fmt '{if(s!="")print s","; s=sprintf(fmt,$8,$1,$2,$3,$4,$5,$6,$7)} END{print s";"}' ${log}
Код: Выделить всё
awk -v fmt=${fmt} 'NR>1{printf ","}{printf fmt, $8,$1,$2,$3,$4,$5,$6,$7} END{print ";"}' ${log}
Мда, Вы все-таки заставили меня засесть за это покапитальнееkpp писал(а):В идеале на выходе awk должен быть полностью весь текст запроса INSERT.
ИМХО.
Все, закругляюсь, что-то меня сегодня занесло
Код: Выделить всё
ip="192.168.0.1"
start="INSERT INTO \`${iface}\` (\`date\`,\`src_ip\`,\`src_port\`,\`dst_ip\`,\`dst_port\`,\`protocol\`,\`packets\`,\`bytes\`) VALUES "
end="(FROM_UNIXTIME(%s),'%s','%s','%s','%s','%s','%s','%s')"
awk -v ip=${ip} -v start="${start}" -v end=${end} '$0!~ip{if(FNR<=1)printf start; else printf ","}\
{printf end, $8,$1,$2,$3,$4,$5,$6,$7} END{print ";"}' ${log} | ${sql}
Код: Выделить всё
if(FNR<=1)printf start; else printf ","
Код: Выделить всё
root@gw02:/usr/ports # service ng_ipacct start
ngctl: send msg: No such file or directory
ngctl: line 2: error in file
/usr/local/etc/rc.d/ng_ipacct: WARNING: netgraph node 'em1_ip_acct' did not created!
Код: Выделить всё
root@gw02:/usr/ports # uname -a
FreeBSD #### 10.0-RELEASE FreeBSD 10.0-RELEASE #1: Thu Feb 20 11:00:52 MSK 2014 adm@####:/usr/obj/usr/src/sys/gw02 amd64
Код: Выделить всё
options IPFIREWALL
options IPFIREWALL_FORWARD
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=100
options IPFIREWALL_NAT
options IPDIVERT
options DUMMYNET
options HZ="1000"
options LIBALIAS
options NETGRAPH
options NETGRAPH_ETHER
options NETGRAPH_IFACE
options NETGRAPH_KSOCKET
options NETGRAPH_SOCKET
options NETGRAPH_TEE
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options SCHED_ULE # ULE scheduler
Код: Выделить всё
# $FreeBSD: ports/net-mgmt/ng_ipacct/files/ng_ipacct.conf,v 1.6 2008/06/03 10:40:16 skv Exp $
#
# Please read and meditate on netgraph(4), ipacctctl(8) and ngctl(8).
# Enable ng_ipacct (i.e. enable run startup script "ng_ipacct.sh")
ng_ipacct_enable="YES"
# Enable kernel modules loading.
# On "ng_ipacct.sh start" all kernel modules specified
# in ${ng_ipacct_modules_list} will be loaded.
# Note: on "ng_ipacct.sh stop" only "ng_ipacct" will be unloaded.
ng_ipacct_modules_load="YES"
# Netgraph can load required ng_* modules automatically on the hook creation
# - except for "ng_ether". Generally, modules preloading is recommended.
# Do not add to this list modules which are statically compiled into kernel.
#ng_ipacct_modules_list="netgraph ng_ether ng_cisco ng_socket ng_tee ng_ipacct"
#ng_ipacct_modules_list="netgraph ng_ether ng_ipacct"
ng_ipacct_modules_list="ng_ipacct"
# List of monitored interfaces. For each interface additional vars must be
# specified in corresponding variables 'ng_ipacct_IFACE_*'.
# See examples below.
ng_ipacct_interfaces="em1"
ng_ipacct_default_ether_start='
name ipfw: ipfw1
mkpeer ipfw1: tee 100 left
name ipfw1:100 %%iface%%_tee
connect ipfw1: 100 200 rightngctl
mkpeer %%iface%%_tee: ipacct left2right %%iface%%_in
name %%iface%%_tee:left2right ip_acct
connect ip_acct: %%iface%%_tee: %%iface%%_out right2left
'
# mkpeer %%iface%%: tee lower right
# name %%iface%%:lower %%iface%%_tee
# connect %%iface%%: lower upper left
# mkpeer %%iface%%_tee: ipacct right2left %%iface%%_in
# name %%iface%%_tee:right2left %%iface%%_ip_acct
# connect %%iface%%_tee: %%iface%%_ip_acct: left2right %%iface%%_out
ng_ipacct_default_ether_stop='
shutdown %%iface%%_ip_acct:
shutdown %%iface%%_tee:
shutdown %%iface%%:
'
ng_ipacct_bpf_ether_start='
name ipfw: ipfw1
mkpeer ipfw1: tee 100 left
name ipfw1:100 %%iface%%_tee
connect ipfw1: 100 200 right
mkpeer %%iface%%_tee: ipacct left2right %%iface%%_in
name %%iface%%_tee:left2right ip_acct
connect ip_acct: %%iface%%_tee: %%iface%%_out right2left
'
ng_ipacct_bpf_ether_stop='
shutdown %%iface%%_ip_acct:
shutdown %%iface%%_bpf:
shutdown %%iface%%_tee:
shutdown %%iface%%:
'
ng_ipacct_em1_dlt="EN10MB" # required line; see ipacctctl(8)
ng_ipacct_em1_threshold="30000" # '5000' by default
ng_ipacct_em1_verbose="yes" # 'yes' by default
ng_ipacct_em1_saveuid="no" # 'no' by default
ng_ipacct_em1_savetime="yes" # 'no' by default
ng_ipacct_em1_start=${ng_ipacct_default_ether_start}
ng_ipacct_em1_stop=${ng_ipacct_default_ether_stop}
ng_ipacct_em1_checkpoint_script="/usr/home/elpaco/scripts/ng_ipacct.sh em1"
# this script is called on "stop" (to save accumulated
# data) or via "rc.d/ng_ipacct.sh checkpoint"
Первый: variables.sh"-list" - для отображения правил
"-stat" - для статических правил
"-test" - для отладки правил
Код: Выделить всё
#!/bin/sh
WanIf=`netstat -rnf inet |awk '/default/{print $6}'` # Интерфейс WAN/oif (outside/внешний)
if [ "${WanIf}" != "" ]; then
WanGw=`netstat -rnf inet |awk '/default/{print $2}'` # WAN/oif (outside/внешний) Gateway/Шлюз по умолчанию
#/sbin/ipfw -q add 1 pass icmp from any to any icmptypes 0,8,11
#if [ "${WanGw}" != "" ] && [ "`ping -i 0.1 -c 5 -t 1 ${WanGw} |awk '/100.0% packet loss/'`" = "" ]; then
#/sbin/ipfw -q delete 1
if [ "${WanGw}" != "" ]; then
WanIp=`ifconfig ${WanIf}|awk '/inet /{print $2}'` # WAN/oif (outside/внешний) IP/адрес
#WanIp=`ifconfig ${WanIf}| grep inet | awk '{print $2}'` # WAN/oif (outside/внешний) IP/адрес
WanNet=`netstat -rnf inet |grep ${WanIf}|awk '/ U /{print $1}'` # WAN/oif (outside/внешняя) Net/сеть
#WanNet=`netstat -rnf inet |awk '/ U /&&/${WanIf}/{print $1}'` # WAN/oif (outside/внешняя) Net/сеть
fi
LanIf=`netstat -rnf inet |grep -v ${WanIf}|awk '/ U /{print $6}'` # Интерфейс LAN (inside/внутренний)
if [ "${LanIf}" != "" ]; then
LanIp=`ifconfig ${LanIf} |awk '/inet /{print $2}'` # LAN/iif (inside/внутренний) IP/адрес
#WanIp=`ifconfig ${LanIf}| grep inet | awk '{print $2}'` # LAN/iif (inside/внутренний) IP/адрес
LanNet=`netstat -rnf inet |grep ${LanIf}|awk '/ U /{print $1}'` # LAN/iif (inside/внутренняя) Net/сеть
#WanNet=`netstat -rnf inet |awk '/ U /&&/${LanIf}/{print $1}'` # LAN/iif (inside/внутренняя) Net/сеть
fi
echo Var1 ${WanIf} ${WanIp} ${WanGw} ${WanNet} ${LanIf} ${LanIp} ${LanGw} ${LanNet} > /tmp/firevall
else
WanIf="rl0" # WAN Интерфейс (outside/внешний)
WanIp="77.37.166.92" # WAN IP-адрес (outside/внешний)
WanGw="77.37.166.1" # WAN Шлюз (outside/внешний)
WanNet="77.37.166.0/23" # WAN IP-сеть (outside/внешний)
LanIf="lan0" # LAN Интерфейс (inside/внутренний)
LanIp="192.168.0.5" # LAN IP-адрес (inside/внутренний)
#LanGw="192.168.1.5" # LAN Шлюз (inside/внутренний)
LanNet="192.168.0.0/24" # LAN IP-сеть (inside/внутренняя)
echo Var2 ${WanIf} ${WanIp} ${WanGw} ${WanNet} ${LanIf} ${LanIp} ${LanGw} ${LanNet}
fi
LoopIf="lo0" # LoopBack интерфейс (петля)
LoopIp="127.0.0.1" # LocalHost IP
LoopNet="127.0.0.0/8" # Сеть LocalHost(Подсеть для коммуникаций внутри хоста)
DmzIf="dmz0" # DMZ Интерфейс (демилитаризованная зона трехдомного типа
#DmzIp="172.16.1.1" # DMZ IP-адрес (демилитаризованная зона)
#DmzGw="172.16.1.1" # DMZ Шлюз (демилитаризованная зона)
DmzNet="172.16.1.0/28" # DMZ IP-сеть (демилитаризованная зона) 172.16.1.0-172.16.1.6
#PppIf="ng0" # PPP Интерфейс (PPPoE VPN клиент)
#PppIp="77.37.166.92" # PPP IP-адрес (PPPoE VPN клиент)
#PppGw="77.37.166.1" # PPP Шлюз (PPPoE VPN клиент)
#PppNet="77.37.166.0/23" # PPP IP-сеть (PPPoE VPN клиент)
VpnIf="ng*" # VPN Интерфейс (PPTP VPN сервер)
VpnGv="192.168.1.232" # VPN IP-адрес (PPTP VPN шлюз)
VpnNet="192.168.1.232/29" # VPN IP-сеть (PPTP VPN подсеть) 192.168.1.233-192.168.1.238
# При включении PPTP VPN сервера, накладывается ограничение на диапазон IP локальной сети
LanNet="$LanNet{1-231}" # LAN IP-сеть (inside/внутренняя) 192.168.1.1-192.168.1.231
OvpnIf="tun0" # OVPN Интерфейс(Open VPN сервер)
OvpnIp="192.168.2.1" # OVPN IP-адрес (Open VPN шлюз)
OvpnNet="192.168.2.0/24" # OVPN IP-сеть (Open VPN подсеть)
# Зарезервированные по RFC 791 адреса которые не должны быть глобально маршрутизируемыми
OwnNet="0.0.0.0/8" # "Своя" сеть (для локального использования на хосте при создании сокетов IP)
MCastNet="224.0.0.0/3" # Class D, E multicast (общегрупповое вещание)
BCastNet="255.255.255.255" # Broadcast
PrivNet="10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16" # RFC 1918 - Приватные сети
DenyNet=$OwnNet", "$PrivNet # Запрещенные сети
DenyNet=$DenyNet", 169.254.0.0/16" # IANA - Канальные (link-local) адреса (IP сеть авто-конфигурации машин без DHCP)
DenyNet=$DenyNet", 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24" # Для примеров в документации.
DenyNet=$DenyNet", 204.152.64.0/23" # Sun Microsystems cluster interconnect (соединения кластеров)
DenyNet=$DenyNet", 240.0.0.0/4" # Зарезервировано для использования в будущем
AdminHost="192.168.1.10,192.168.1.20,192.168.0.10,192.168.0.20" # Компьютеры локальной сети, которым разрешен привелегированный доступ
DenyHost="192.168.1.30,192.168.1.40" # Компьютеры локальной сети, которым запрещен доступ в internet
PubPort="0-1023" # RFC 4340 Общеизвестные порты используемые процессами системы или прикладными программами, запущенные привилегированными пользователями
RegPort="1024-49151" # RFC 4340 Зарегистрированные порты используемые процессами обычных пользователей или программами, запущенными обычными пользователями
DynPort="49152-65535" # Клиентские порты используемые внутри закрытых сетей - для временного использования
# Запрещенные порты, по которым требуется посылка уведомления (RST), для ускорения работы приложений удаленного сервера/клиента
ResetPort="113" # RFC 1413 запрет ident
# Запрещенные на отправку в Интернет порты Netbios/Samba
DenyPort="135" # Windows (функция отображения конечных точек RPC) (COM/DCOM, DFS, журнал событий, репликация файлов, очереди сообщений и MsOutlook.)
DenyPort=$DenyPort",137,138,139,445" # Netbios/Samba 137=name, 138=datagram, 139=session (браузер поиска компьютеров, службы совместного использования файлов, Net Logon и служба сервера), 445 (доступ к файлам, принтерам и другим сетевым ресурсам, межпроцессное взаимодействие)
DenyPort=$DenyPort",389,636" # ldap и ldaps (sldap)
DenyPort=$DenyPort",520" # RIP протокол дистанционно-векторной маршрутизации по умолчанию вещает в сеть свою полную таблицу маршрутизации раз в 30 секунд, довольно сильно нагружая низкоскоростные линии связи.
DmzUdp="" # Открытые на серверах DMZ сервисы/порты "smtp/smtps,http,https,pop3/pop3s"
DmzTcp="25,465,80,443,110,995" # Открытые на серверах DMZ сервисы/порты "smtp/smtps,http,https,pop3/pop3s"
WanUdp="1194" # Открытые на сервере сервисы/порты "openvpn" за исключением ssh
#WanTcp="25,80,110,1723" # Открытые на сервере сервисы/порты "ftp,smtp,http,pop3,pptp" за исключением ssh
WanTcp="1723" # Открытые на сервере сервисы/порты "ftp,smtp,http,pop3,pptp" за исключением ssh
LanUdp="53,67,123,137,138" # Открытые на сервере сервисы/порты "dns,dhcp,ntp,samba"
LanTcp="21,22,25,53,80,110,139,445,1723,1194,3306,5006,9091" # Открытые на сервере сервисы/порты "ftp,ssh,smtp,dns,dhcp,http,pop3,pptp,openvpn,mysql,mpd5,transmission"
AdmTcp="20,22,25,465,53,110,1723" # Разрешенные администраторам сервисы/порты "ftp-data,ftp,ssh,smtp/smtps,domain,http,https,pop3/pop3s,pptp,aol"
AdmUdp="53,443,955,1194" # Разрешенные администраторам UDP сервисы/порты "domain,OpenVpn,OpenVpn"
UsrUdp="123" # Разрешенные пользователям сервисы/порты "ftp,http,https,aol"
UsrTcp="21,80,443,8080,5190" # Разрешенные пользователям сервисы/порты "ftp,http,https,aol"
BsdTcp="5999" # Разрешенные Jail серверам сервисы/порты "CVSup"
Код: Выделить всё
#!/bin/sh
## Сброс и инициализация переменных, ограничений, очередей, таблиц, функций ###
#- Инициализация переменных скрипта ------------------------------------------#
ssys="set 0"; sbug="set 29"; sfnp="set 30" # $ssys-обязательные, $sbug-отладка, $sfnp-fingerprinting/antispoofing
swan="set 1"; sdmz="set 2"; sppp="set 3" # Правила на внешних интерфейсах $swan-WAN, $sdmz-DMZ, $sppp-PPP,
slan="set 4"; svpn="set 5"; sovpn="set 6" # Правила на внутренних интерфейсах $slan-LAN, $svpn-VPN, $sovpn-OVPN
snat="set 10"; spip="set 11"; sque="set 12" # Правила $snat=NAT, $spip=Pipe, $sque=Queue
l0=""; l1="log logamount 10"; l2="log logamount 100"; l3="log logamount 1000" # Количество записей по правилу
inc=10; SStart=100; SysEnd=65000 # Значение шага динамической генерации номеров правил. Стартовое значение счетчика первичных и завершающих павил.
WanIn=1000; DmzIn=2000; PppIn=3000; LanIn=4000; VpnIn=5000; OvpnIn=6000 # Стартовое значение счетчика правил по каждому интерфейсу для ф-ии ip_input()
WanOut=1500; DmzOut=2500; PppOut=3500; LanOut=4500; VpnOut=5500; OvpnOut=6500 # Стартовое значение счетчика правил по каждому интерфейсу для ф-ии ip_output()
. /etc/ipfw/variables.sh # Запуск скрипта установки и инициализации переменных
#- Инициализация функций -----------------------------------------------------#
dyncmd () { eval ${fwcmd} add \$${1} ${@##${1}}; eval ${1}=$((${1}+${inc})); } # Функция динамичекой генерации номеров правил
setup_loopback () { # Функция обязательных правил LoopBack интерфейса
dyncmd "SStart" $ssys allow ip from any to any via ${LoopIf} # Трафик через LoopBack интерфейс $LoopIf
dyncmd "SStart" $ssys deny ip from any to ${LoopNet} # Запрет трафика на подсеть хоста на всех интерфейсах
dyncmd "SStart" $ssys deny ip from ${LoopNet} to any # Запрет трафика из подсети хоста на всех интерфейсах
}
natWanIn () { # Пример: natWanIn "$l1" "tcp" "192.168.1.10" "3389" "10389" "$sl2" # Функция создания комплекта правил для проброса порта с внешнего интерфейса на адрес локальной сети
dyncmd "WanIn" $snat nat 1 $1 $2 from any to ${WanIp} $5 in recv ${WanIf} $6
dyncmd "WanOut" $snat nat 1 $1 $2 from $3 $4 to any out xmit ${WanIf} established
dyncmd "LanIn" $snat allow $1 $2 from $3 $4 to any in recv ${LanIf}
dyncmd "LanOut" $snat allow $1 $2 from any to $3 $4 out xmit ${LanIf}
}
natLanOut () { # Пример: #natLanOut "$l1" "tcp" "192.168.1.10" "87.250.250.203" "9595" "$sl6" # Функция создания комплекта правил для выхода в интернет с локальной сети
local notLanIp=$4; local setEstablished="established"
if [ "${6##setup*}" != "" ]; then setEstablished=""; fi
if [ "$4" == "any" ]; then notLanIp="not ${LanIp}"; fi
dyncmd "WanIn" nat 1 $1 $2 from $4 $5 to ${WanIp} in recv ${WanIf} $setEstablished
#dyncmd "WanIn" $snat check-state
dyncmd "WanOut" skipto $((${WanOut}+${inc})) $1 $2 from $3 to $4 $5 out xmit ${WanIf} $6
#dyncmd "WanIn" $snat deny $1 $2 from $3 $4 to any in recv ${WanIf} established
#dyncmd "WanIn" $snat deny $1 $2 from any to any in recv ${WanIf}
#dyncmd "WanOut" $snat deny $1 $2 from any to any out xmit ${WanIf}
dyncmd "WanOut" nat 1 $1 $2 from $3 to $4 $5 out xmit ${WanIf}
dyncmd "LanIn" allow $1 $2 from $3 to $notLanIp $5 in recv ${LanIf}
dyncmd "LanOut" allow $1 $2 from $notLanIp $5 to $3 out xmit ${LanIf}
}
configMini () { # Функция создания минимально-достаточного набора проверенно-работающих статических правил
setup_loopback # Добавление обязательных правил LoopBack интерфейса
dyncmd "SStart" $ssys check-state # Разрешение установленных соединений
dyncmd "WanIn" $swan fwd ${LoopIp},22 $l1 tcp from any to ${WanIp} "10122" in recv ${WanIf} $ks # Разрешение подключения по SSH(22) из интернета
dyncmd "WanIn" $swan fwd ${LoopIp},21 $l1 tcp from any to ${WanIp} "10121" in recv ${WanIf} $ks # Разрешение подключения по FTP(21) из интернета
dyncmd "WanIn" $swan fwd ${LoopIp},1194 $l1 tcp from any to ${WanIp} "10194 " in recv ${WanIf} $ks # Разрешение подключения по OpenVPN(1194) из интернета
dyncmd "WanIn" $sfnp deny $l1 ip from "'table(1)'" to any in recv ${WanIf} # Запрет не маршрутизируемого трафика
dyncmd "WanIn" $swan allow $l1 icmp from any to ${WanIp} in recv ${WanIf} icmptypes "8" # Разрешение входящих пингов (RFC 792 ICMP)
for i in `echo ${WanTcp}|sed 's/,/ /g'`; do # Разрешение подключений к серверу из интернета на разрешенные порты
dyncmd "WanIn" $swan allow $l1 tcp from any to ${WanIp} $i in recv ${WanIf} ; done #
dyncmd "WanOut" $swan allow $l1 ip from me to any out xmit ${WanIf} $ks # Разрешение серверу выходить в интернет
dyncmd "WanIn" $snat nat 1 $l1 ip from any to any in recv ${WanIf} # Включение NAT-а для всех подключений на внешнем интерфейсе
dyncmd "WanOut" $snat nat 1 $l1 ip from any to any out xmit ${WanIf} #
dyncmd "LanIn" $slan allow $l1 ip from any to any in recv ${LanIf} # Разрешение все для всех на внутреннем интерфейсе
dyncmd "LanOut" $sbug allow $l1 ip from any to any out xmit ${LanIf} #
dyncmd "VpnIn" $svpn allow $l1 ip from ${VpnNet} to ${LanNet} in recv ${VpnIf} $ks # Разрешение из VPN сети в локалку
dyncmd "OvpnOut" $sovpn allow $l1 ip from ${OvpnNet} to ${LanNet} in recv ${OvpnIf} $ks # Разрешение "все для всех" из VPN сети
}
deny_fnp_spoof () { # Функция защиты от fingerprinting и antispoofing на входящем трафике WAN
#dyncmd "WanIn" $sfnp deny $l1 ip from any to not ${WanIp} in recv ${WanIf} # Анти спуфинг - Запрет пакетов адресованных не серверу
dyncmd "WanIn" $sfnp deny $l1 ip from "'table(1)'" to any in recv ${WanIf} # Запрет не маршрутизируемого трафика
dyncmd "WanIn" $sfnp deny $l1 ip from any to ${WanIp} in recv ${WanIf} ipoptions ssrr # Запрет пакетов с нестандартными IP-опциями
dyncmd "WanIn" $sfnp deny $l1 ip from any to ${WanIp} in recv ${WanIf} ipoptions lsrr
dyncmd "WanIn" $sfnp deny $l1 ip from any to ${WanIp} in recv ${WanIf} ipoptions rr
dyncmd "WanIn" $sfnp deny $l1 ip from any to ${WanIp} in recv ${WanIf} ipoptions ts # Запрет пакетов с Timestamp
dyncmd "WanIn" $sfnp deny $l1 tcp from any to ${WanIp} in recv ${WanIf} tcpflags !syn, !ack, !rst # Запрет NULL-пакетов (без единого флага) - второй тест nmap
dyncmd "WanIn" $sfnp deny $l1 tcp from any to ${WanIp} in recv ${WanIf} tcpflags syn, fin, urg, psh, !ack # Запрет XMAS-пакетов - третий тест nmap
dyncmd "WanIn" $sfnp deny $l1 tcp from any to ${WanIp} in recv ${WanIf} tcpflags syn, fin, !ack
dyncmd "WanIn" $sfnp deny $l1 tcp from any to ${WanIp} in recv ${WanIf} tcpflags fin, urg, psh, !ack # Седьмой тест nmap
dyncmd "WanIn" $sfnp deny $l1 tcp from any to ${WanIp} in recv ${WanIf} tcpflags fin, !ack
dyncmd "WanIn" $sfnp deny $l1 tcp from any to ${WanIp} in recv ${WanIf} tcpflags urg, !ack
dyncmd "WanIn" $sfnp deny $l1 tcp from any to ${WanIp} in recv ${WanIf} tcpflags psh, !ack
dyncmd "WanIn" $sfnp deny $l1 tcp from any to ${WanIp} in recv ${WanIf} tcpflags fin, syn, rst, psh, ack, urg # Запрет X-сканирования:
dyncmd "WanIn" $sfnp deny $l1 tcp from any to ${WanIp} in recv ${WanIf} tcpflags !fin, !syn, !rst, !psh, !ack, !urg # Запрет NULL-сканирования:
dyncmd "WanIn" $sfnp deny $l1 tcp from any to ${WanIp} in recv ${WanIf} not established tcpflags fin # Запрет FIN-сканирования:
dyncmd "WanIn" $sfnp deny $l1 ip from any to ${WanIp} in recv ${WanIf} not verrevpath in # Защита от спуфинга
#${fwcmd} set disable $sfnp # enable/disable правил ОТЛАДКА.
}
#- Разделение на отладку и применение правил----------------------------------#
if [ "${1}" == "-list" ]; then fwcmd="echo ipfw" # Запуск скрипта c опцией "-list" - для отображения правил
if [ "${2}" != "-stat" ]; then ks="keep-state"; fi # Запуск скрипта c опцией "-stat" - для статических правил
elif [ "${1}" == "-test" ]; then fwcmd="/sbin/ipfw -n" # Запуск скрипта c опцией "-test" - для отладки правил
if [ "${2}" != "-stat" ]; then ks="keep-state"; fi # Запуск скрипта c опцией "-stat" - для статических правил
else # Запуск скрипта в рабочем режиме - для применения правил
if [ "${1}" != "-stat" ]; then ks="keep-state"; fi # Запуск скрипта c опцией "-stat" - для статических правил
#- Сброс(удаление) всех правил, пайпов, очередей, таблиц ---------------------#
fwcmd="/sbin/ipfw -q" # Подавление информационных сообщений при добавлении правил
${fwcmd} -f flush # Сброс правил
#${fwcmd} -f pipe flush # Сброс ограничителей ширины канала
#${fwcmd} -f queue flush # Сброс очередей
${fwcmd} -f table all flush # Сброс всех таблиц
for i in `${fwcmd} nat show config |awk '{print $3}'`; do ${fwcmd} nat $i delete; done # Сброс всех правил нат
#- Инициализация переменных SYSCTL -------------------------------------------#
#${fwcmd} -f enable one_allow #sysctl net.inet.ip.fw.one_allow=1 # Пакеты, перенаправляемые мостом, обрабатываются ipfw один раз
${fwcmd} -f enable verbose #sysctl net.inet.ip.fw.verbose=1 # Включение выдачи более подробных сообщений.
${fwcmd} -f enable debug #sysctl net.inet.ip.fw.debug=1 # Включение отладочных сообщений.
#sysctl net.inet.ip.fw.verbose_limit=0 # Ограничение количества сообщений. 0 - без ограничений
#sysctl net.inet.ip.fw.autoinc_step=10 # inc=10 # Установка разности между номерами правил при их автогенерации
#sysctl net.inet.ip.fw.default_to_accept=0 # Правило по умолчанию, 0-доступ запрещен
#- Инициализация таблиц ------------------------------------------------------#
for i in ${DenyNet}; do ${fwcmd} table 1 add $i; done # Создание таблицы(1) приватных сетей
for i in `echo ${DenyHost}|sed 's/,/ /g'`; do ${fwcmd} table 2 add $i; done # Создание таблицы(2) блокированных хостов
for i in `echo ${AdminHost}|sed 's/,/ /g'`; do ${fwcmd} table 3 add $i; done # Создание таблицы(3) административных хостов
#- Инициализация объектов NAT, pipe, queue -----------------------------------#
${fwcmd} nat 1 config log if ${WanIf} reset deny_in same_ports unreg_only redirect_port tcp 192.168.1.10:3389 10389 # Включить nat 1 на внешнем интерфейсе, Включить редирект на внутренний RDP
#${fwcmd} pipe 1 config bw 7Mbit/s queue 10 # исходящая
#${fwcmd} pipe 2 config bw 7Mbit/s queue 10 # входящая
#${fwcmd} queue 1 config mask src-ip 0xffffffff pipe 1 queue 70 gred 0.002/15/35/0.2 #
#${fwcmd} queue 2 config mask dst-ip 0xffffffff pipe 2 queue 70 gred 0.002/15/35/0.2 #
if [ "${1}" == "-mini" ]; then configMini; exit; fi # Запуск скрипта c опцией "-mini" - для минимальных правил
fi
#- Инициализация переменных и правил для динамических правил -----------------#
if [ "$ks" != "" ]; then sks="setup $ks"; sl="setup limit src-addr";
sl2="$sl 2"; sl4="$sl 8"; sl6="$sl 32"; sl7="$sl 64"; sl8="$sl 128"; # 1-1/2-2/3-4/4-8/5-16/6-32/7-64/8-128
dyncmd "SStart" $ssys check-state ; fi # Разрешение установленных соединений
###############################################################################
## Правила IPFW ###############################################################
#-($SStart) Стартовые правила -----------------------------------------------#
setup_loopback # Обязательные правила LoopBack интерфейса
#-(00300) Подсчет всего трафика в интернет и обратно -------------------------#
#dyncmd "SStart" $ssys count $l0 ip from ${WanIp} to not ${LanNet} out via $WanIf
#dyncmd "SStart" $ssys count $l0 ip from not ${LanNet} to ${WanIp} in via $WanIf
#-(00400) Правила распределения по ф-ям ip_input/ip_output и интефейсам ------#
dyncmd "SStart" $ssys skipto ${WanIn} ip from any to any in via ${WanIf} # ip_input()
dyncmd "SStart" $ssys skipto ${DmzIn} ip from any to any in via ${DmzIf}
#dyncmd "SStart" $ssys skipto ${PppIn} ip from any to any in via ${PppIf}
dyncmd "SStart" $ssys skipto ${LanIn} ip from any to any in via ${LanIf}
dyncmd "SStart" $ssys skipto ${VpnIn} ip from any to any in via ${VpnIf}
dyncmd "SStart" $ssys skipto ${OvpnIn} ip from any to any in via ${OvpnIf}
dyncmd "SStart" $ssys skipto ${WanOut} ip from any to any out via ${WanIf} # ip_output()
dyncmd "SStart" $ssys skipto ${DmzOut} ip from any to any out via ${DmzIf}
#dyncmd "SStart" $ssys skipto ${PppOut} ip from any to any out via ${PppIf}
dyncmd "SStart" $ssys skipto ${LanOut} ip from any to any out via ${LanIf}
dyncmd "SStart" $ssys skipto ${VpnOut} ip from any to any out via ${VpnIf}
dyncmd "SStart" $ssys skipto ${OvpnOut} ip from any to any out via ${OvpnIf}
#-($WanIn) Трафик WAN входящий - in recv ${WanIf} ---------------------------#
deny_fnp_spoof # Защита от fingerprinting и antispoofing на входящем трафике WAN --#
dyncmd "WanIn" $swan fwd ${LoopIp},22 $l1 tcp from any to ${WanIp} "10122" in recv ${WanIf} $sl2 # Разрешение подключения по SSH(22) из интернета
dyncmd "WanIn" $swan fwd ${LanIp},21 $l1 tcp from any to ${WanIp} "10121" in recv ${WanIf} $sl2 # Разрешение подключения по FTP(21) из интернета
dyncmd "WanIn" $swan fwd ${LoopIp},1194 $l1 tcp from any to ${WanIp} "10194 " in recv ${WanIf} $sl2 # Разрешение подключения по OpenVPN(1194) из интернета
dyncmd "WanIn" $swan fwd 172.16.1.1,80 $l1 tcp from any to ${WanIp} "8080" in recv ${WanIf} $sl8 # Разрешение подключения по WWW(80) из интернета в зону DMZ
dyncmd "WanIn" $swan fwd 172.16.1.1,80 $l1 tcp from any to ${WanIp} "80" in recv ${WanIf} $sl8 # Разрешение подключения по W
dyncmd "WanIn" $swan allow $l1 icmp from any to ${WanIp} in recv ${WanIf} icmptypes "8" $ks # Разрешение входящих пингов (RFC 792 ICMP)
dyncmd "WanIn" $swan allow $l1 udp from any to ${WanIp} "10413" in recv ${WanIf} $ks # Разрешение torrent - Transmission
dyncmd "WanIn" $swan allow $l1 tcp from any to ${WanIp} "10413" in recv ${WanIf} $sks # Разрешение torrent - Transmission
#dyncmd "WanIn" $swan allow $l1 udp from any "67" to ${WanIp} "68" in recv ${WanIf} $ks # DHCP (UDP 77.37.166.92:68 77.37.128.2:67 out via rl0)
#dyncmd "WanIn" $swan allow $l1 ospf from any to any in recv ${WanIf} #
for i in `echo ${WanTcp}|sed 's/,/ /g'`; do # Разрешение подключений к серверу из интернета на разрешенные порты
dyncmd "WanIn" $swan allow $l1 tcp from any to ${WanIp} $i in recv ${WanIf} $sl7; done
#-($WanIn) NAT входящего трафика WAN - in recv ${WanIf} ----------------------#
dyncmd "WanIn" $snat nat 1 $l1 gre from any to ${WanIp} in recv ${WanIf} # compressed PPP data
natWanIn "$l1" "tcp" "192.168.1.10" "3389" "10389" "$sl2"
#-($WanOut) Трафик WAN исходящий - out xmit ${WanIf} -------------------------#
dyncmd "WanOut" $sfnp deny $l1 ip from any to any ${DenyPort} out xmit ${WanIf} # Запрет отправки в Интернет пакетов Netbios/Samba
dyncmd "WanOut" $swan allow $l1 udp from ${WanIp} "68" to any "67" out xmit ${WanIf} $ks # DHCP (UDP 77.37.166.92:68 77.37.128.2:67 out via rl0)
dyncmd "WanOut" $swan allow $l1 udp from ${WanIp} to any "53" out xmit ${WanIf} $ks # Разрешение DNS запросов 53-"domain"
#dyncmd "WanOut" $swan allow $l1 tcp from ${WanIp} to any "53" out xmit ${WanIf} $sks # Разрешение DNS запросов
dyncmd "WanOut" $swan allow $l1 udp from ${WanIp} to any "123" out xmit ${WanIf} $ks # Разрешение NTP запросов
dyncmd "WanOut" $swan allow $l1 udp from ${WanIp} "10413" to any out xmit ${WanIf} $ks # Разрешение torrent - Transmission
#dyncmd "WanOut" $sbug allow $l1 icmp from ${WanIp} to any out xmit ${WanIf} $ks # ОТЛАДКА. Разрешение серверу ходить в инет
#dyncmd "WanOut" $sbug allow $l1 udp from ${WanIp} to any out xmit ${WanIf} $ks # ОТЛАДКА. Разрешение серверу ходить в инет
#dyncmd "WanOut" $sbug allow $l1 tcp from ${WanIp} to any out xmit ${WanIf} $sks # ОТЛАДКА. Разрешение серверу ходить в инет
#-($WanOut) NAT исходящего трафика WAN - out xmit ${WanIf} -------------------------#
dyncmd "WanOut" $snat nat 1 $l1 gre from ${WanIp} to any out xmit ${WanIf} # compressed PPP data
#-($WanOut) Трафик WAN с локальной сети в интернет - out recv ${LanIf} xmit ${WanIf}#
#dyncmd "WanOut" $swan allow $l1 tcp from ${LanNet} to any "pptp" out recv ${LanIf} xmit ${WanIf} $sks # Разрешение VPN запросов Microsoft Point-to-Point Tunneling Protocol (PPTP)
#-($DmzIn) Трафик DMZ входящий - in recv ${DmzIf} ---------------------------#
#dyncmd "DmzIn" $sdmz nat 1 $l1 tcp from any "5999" to ${WanIp} in recv rl0 established # csup/cvsup
#dyncmd "DmzIn" $sdmz nat 1 $l1 tcp from any to ${WanIp} "6849152-65535" in recv rl0 established # fetch FTP passive
#dyncmd "DmzIn" $sbug allow $l1 icmp from any to ${DmzNet} in recv ${DmzIf} $ks # ОТЛАДКА. Разрешение серверу ходить в инет
#dyncmd "DmzIn" $sbug allow $l1 udp from any to ${DmzNet} in recv ${DmzIf} $ks # ОТЛАДКА. Разрешение серверу ходить в инет
#dyncmd "DmzIn" $sbug allow $l1 tcp from any to ${DmzNet} in recv ${DmzIf} $sks # ОТЛАДКА. Разрешение серверу
dyncmd "DmzIn" $sdmz allow $l1 tcp from any to 172.16.1.1 "80" in recv ${DmzIf} $sks # Разрешение подключений к WWW серверу
#-($DmzOut) Трафик DMZ исходящий - out xmit ${DmzIf} -------------------------#
dyncmd "DmzOut" $sdmz nat 1 $l1 icmp from ${DmzNet} to any out xmit ${DmzIf} icmptypes "0,8" $ks # Разрешение ping-ов из DMZ с
dyncmd "DmzOut" $sdmz allow $l1 icmp from ${DmzNet} to any out xmit ${DmzIf} icmptypes "0,8" # Разрешение ping-ов из DMZ сети
#dyncmd "DmzOut" $sbug allow $l1 udp from ${DmzNet} to any out xmit ${DmzIf} $ks # ОТЛАДКА. Разрешение серверу ходить в инет
#dyncmd "DmzOut" $sbug allow $l1 tcp from ${DmzNet} to any out xmit ${DmzIf} $sks # ОТЛАДКА. Разрешение серверу
dyncmd "DmzOut" $sdmz nat 1 $l1 tcp from 172.16.1.1 to any "21,80,443" out xmit ${WanIf} $sks # Разрешение серверу WWW подключаться на порты 21,80,443
dyncmd "DmzOut" $sdmz allow $l1 tcp from 172.16.1.1 "80" to any out xmit ${DmzIf} # Разрешение серверу WWW подключаться на порты 21,80,443
dyncmd "DmzOut" $sbug allow $l1 udp from ${LanIp} "53,123" to ${DmzNet} out xmit ${DmzIf} $ks # Разрешение DMZ сети обращаться к DNS и NTP
#-($DmzOut) Трафик DMZ с интернета в DMZ - out recv ${WanIf} xmit ${DmzIf} ---#
#-($PppIn) Трафик PPP входящий - in recv ${PppIf} ---------------------------#
#dyncmd "PppIn" $snat nat 2 $l1 ip from any to ${PppIp} in via ${PppIf}
#-($PppOut) Трафик PPP исходящий - out xmit ${PppIf} -------------------------#
#dyncmd "PppOut" $snat nat 2 $l1 ip from ${LanNet} to any out via ${PppIf}
#-($PppOut) Трафик PPP с интернета в PPP - out recv ${WanIf} xmit ${PppIf} ---#
#-($LanIn) Трафик LAN входящий - in recv ${LanIf} ---------------------------# #- Транзитный трафик из локалки в интернет будет преобразован роутером в out xmit ${WanIf} и уже в таком виде попадает в NAT
#dyncmd "LanIn" $sfnp deny $l1 ip from any to not ${LanIp} in recv ${LanIf} # Анти спуфинг - Запрет пакетов адресованных не серверу
#dyncmd "LanIn" $sfnp deny $l1 ip from ${WanNet} to any in recv ${LanIf} # Анти спуфинг - Запрет перекрестных пакетов
dyncmd "LanIn" $sfnp reset $l1 ip from ${LanNet} to any ${ResetPort} in recv ${LanIf} # Отвергать пакеты на данные порты с посылкой уведомлений
dyncmd "LanIn" $slan deny $l1 ip from "'table(2)'" to not ${LanIp} in recv ${LanIf} # Запрет доступа в internet заблокированным компьютерам локальной сети
dyncmd "LanIn" $slan allow $l1 udp from ${LanNet} "68" to ${LanIp} "67" in recv ${LanIf} $ks # DHCP (UDP 192.168.1.10:68 192.168.1.5:67 in via em0)
dyncmd "LanIn" $slan allow $l1 udp from ${LanNet} "68" to ${BCastNet} "67" in recv ${LanIf} # DHCP (UDP 192.168.1.10:68 255.255.255.255:67 in via em0)
dyncmd "LanIn" $slan allow $l1 udp from ${OwnNet} "68" to ${BCastNet} "67" in recv ${LanIf} # DHCP (UDP 0.0.0.0:68 255.255.255.255:67 in via em0)
dyncmd "LanIn" $slan allow $l1 udp from ${LanNet} to ${LanIp} "53" in recv ${LanIf} $ks # Разрешение запросов к DNS серверу
dyncmd "LanIn" $slan allow $l1 icmp from ${LanNet} to ${LanIp} in recv ${LanIf} icmptypes "0,3,4,8,11,12" $ks # Разрешение из локалки Ping-а к серверу
dyncmd "LanIn" $slan allow $l1 udp from ${LanNet} to ${LanIp} ${LanUdp} in recv ${LanIf} $ks # Разрешение входящих подключений к портам разрешенных сервисов сервера
dyncmd "LanIn" $slan allow $l1 tcp from ${LanNet} to ${LanIp} ${LanTcp} in recv ${LanIf} $sks # Разрешение входящих подключений к портам разрешенных сервисов сервера
#dyncmd "LanIn" $slan fwd {LoopIp},3128 $l1 tcp from ${LanNet} to not ${LanNet} "80,3128,8000,8001,8080,8081,443,21" in recv ${LanIf} $sks
#-($LanOut) Трафик LAN исходящий - out xmit ${LanIf} -------------------------#
dyncmd "LanOut" $sbug allow $l1 ip from me to any out xmit ${LanIf} $ks # ОТЛАДКА. Серверу выход на внутреннем интерфейсе
#-($LanOut) NAT трафика с ${LanNet} в интернет - out xmit ${LanIf} -----------#
natLanOut "$l1" "udp" "${LanNet}" "any" "${UsrUdp}" "$ks" # Разрешение локалке ходить в инет на разрешенные порты
natLanOut "$l1" "tcp" "${LanNet}" "any" "${UsrTcp}" "$sks" # Разрешение локалке ходить в инет на разрешенные порты
natLanOut "$l1" "icmp" "'table(3)'" "any" "" "$ks" # Разрешение админам пинговать хосты в интернете
natLanOut "$l1" "udp" "'table(3)'" "any" "${AdmUdp}" "$ks" # Разрешение админам ходить в инет на разрешенные админские UDP порты
natLanOut "$l1" "tcp" "'table(3)'" "any" "${AdmTcp}" "$sl2" # Разрешение админам ходить в инет на разрешенные админские TCP порты
#-($LanOut) Трафик LAN с интернета в локальную сеть - out recv ${WanIf} xmit ${LanIf}#
#dyncmd "LanOut" $sbug allow $l1 tcp from ${LanNet} to any out recv ${WanIf} xmit ${LanIf} $sks # ОТЛАДКА.
#-($VpnIn) Трафик VPN входящий - in recv ${VpnIf} ---------------------------#
#dyncmd "VpnIn" $svpn allow $l1 ip from any to any verrevpath via ${VpnIf} # ОТЛАДКА. Разрешение "все для всех" из VPN сети
dyncmd "VpnIn" $svpn allow $l1 ip from ${VpnNet} to ${LanNet} in recv ${VpnIf} $ks # Разрешение из VPN сети в локалку
#-($VpnOut) Трафик VPN исходящий - out xmit ${VpnIf} -------------------------#
#dyncmd "VpnOut" $svpn allow $l1 ip from ${LanNet} to ${VpnNet} out xmit ${VpnIf} # Разрешение из локалки в VPN сеть
#-($VpnOut) Трафик VPN с интернета на VPN - out recv ${WanIf} xmit ${VpnIf} --#
#-($OvpnIn) Трафик OVPN входящий - in recv ${OvpnIf} ------------------------#
dyncmd "OvpnOut" $sovpn allow $l1 ip from ${OvpnNet} to ${LanNet} in recv ${OvpnIf} $ks # Разрешение "все для всех" из VPN сети
#-($OvpnOut) Трафик OVPN исходящий - out xmit ${OvpnIf} ----------------------#
#dyncmd "OvpnOut" $sovpn allow $l1 ip from ${LanNet} to ${OvpnNet} out xmit ${OvpnIf} # ОТЛАДКА. Разрешение "все для всех" из VPN сети
#-($OvpnOut) Трафик OVPN с интернета на VPN - out recv ${WanIf} xmit ${VpnIf}-#
#dyncmd "SysEnd" $sbug allow $l1 ip from any to any # ОТЛАДКА. Разрешение "все для всех" из VPN сети
dyncmd "SysEnd" $sbug deny $l1 ip from any to any # ОТЛАДКА. Запрет "все для всех" из VPN сети
# ===============================================================
if [ "${1}" == "-temp" ]; then sleep 300; exec $0 '-mini'; fi # Запуск скрипта c опцией "-temp" - для отката на минимальный конфиг через 5 мин
Код: Выделить всё
#п п?я?я?п?пҐя?п?п?.JPG --> 2008-04-21_15-56-06_п?п?я?я?п?пҐя?п?п?.JPG # Console: KOI8-U Locale: CP1251
#Каштанчик.JPG --> 2008-04-21_15-56-06_ЊаштанчШЪ.JPG # Console: UTF-8 Locale: CP1251
#Памятник.JPG --> 2008-04-21_14-07-28_ЏаУятнШЪ.JPG # Console: UTF-8 Locale: CP1251
Код: Выделить всё
#!/bin/sh
BASE_DIR="/shared/photo/import" # Калог откуда будут разбираться файлы.
TEMP_DIR="/shared/photo/razbor" # Каталог куда временно перемещаются дубли и "НЕ правильные" файлы для ручного разбора
#
SORT_DIR="/shared/photo/sorted" # Каталог куда перемещаются "правильные" файлы
DATA_DIR="/shared/photo/source" # Каталог куда перемещаются "RAW/сырцы" файлы
#
PRIV_DIR="/shared/photo/privat" # Каталог для личных файлов
# Файлы [JPEG image data] содержащие [EXIF standard/JFIF standard/IPTC standard]
FILE_EXIF="JPG;JPE;JPEG;JFIF;MPO"
FILE_EXIF_DATA="JPEG_image_data"
# Файлы [raw image data]
FILE_RAW="ERF;CRW;CR2;NEF;NRW;MRW;PTX;PEF;ARW;SRW;SRF;SR2;ORF;RAF;DNG;DCR;KDC"
FILE_RAW_DATA="raw_image_data"
# Файлы содержащие [Apple QuickTime movie/MPEG sequence/Motion JPEG]
FILE_VIDEO="AVI;MOV;MPG;MP4;3GP" #"ASF;ASX;BIK;DIVX;QT;IFO;MPEG;MPG4;OGM;RM;RMV;SMK;XVID;VOB;WM;WMV"
FILE_PICTURE="BMP;GIF;TIF;PNG;PSD" #"ANI;CUR;DIB;EMF;EPS;ICN;ICL;ICO;IFF;LBM;RLE;PBM;PCD;PCX;PGM;PIC;PIX;PSP;TIFF;TGA;XIF;WMF;XBM;XPM"
# move_exiv_file
move_exiv_file(){
FILE_DATA=`echo $3 | sed 's/_/ /g'`; FILE_DIR=$1
#----------------------------------------- Выполнение цикла по каждому расширению -------------------------------------------#
for FILE_EXT in `echo $2| sed 's/;/ /g'` ; do
#-------------------------- Выполнение цикла по каждому файлу с соответствующим расширением -------------------------#
find "$BASE_DIR" -name "*.$FILE_EXT" | sort | while read FILE_PATH ; do
#------------------------- Секция проверки файла на соответствие формату и EXIM даты ------------------------#
if ! file "$FILE_PATH" | grep -q "$FILE_DATA" ; then continue ; fi
for EXIM_DATA in "Exif.Photo.DateTimeOriginal" "Exif.Photo.DateTimeDigitized" "Exif.Image.DateTime" ; do
PHOTO_DATE=`exiv2 -g "$EXIM_DATA" -Pv "$FILE_PATH" | awk '{ print $1 }' | sed 's/[-_\.,/\]/:/g;s/[ ]//g;s/0000//g'` > /dev/null
PHOTO_TIME=`exiv2 -g "$EXIM_DATA" -Pv "$FILE_PATH" | awk '{ print $2 }' | sed 's/[-_\.,/\]/:/g;s/[ ]//g'` > /dev/null
if [ -n "$PHOTO_DATE" ] && [`echo -n "$PHOTO_DATE" | wc -c` -eq 10 ]; then break ; fi
done
#--------------------------- Переносятся только файлы с существующим и верным EXIF --------------------------#
if [ -z "$PHOTO_DATE" ] || [`echo -n "$PHOTO_DATE" | wc -c` -ne 10 ] ; then continue ; fi
FILE_DATE=`stat -f%Sm -t'%Y:%m:%d' "$FILE_PATH"`; FILE_TIME=`stat -f%Sm -t'%H:%M:%S' "$FILE_PATH"` ; MOVE_DIR=""
#------- Преобразование формата даты - если год идет последним dd:mm:YYYY надо поменять на YYYY:mm:dd -------#
if [ `echo -n "$PHOTO_DATE" | awk -F: '{print $3}' | wc -c` -eq 5 ] ; then
PHOTO_DATE=`date -j -f "%d:%m:%Y" "$PHOTO_DATE" "+%Y:%m:%d"`
if [ "$PHOTO_DATE" != "$FILE_DATE" ] ; then MOVE_DIR="$TEMP_DIR" ; fi
exiv2 -M"set $EXIM_DATA Ascii $PHOTO_DATE $PHOTO_TIME" "$FILE_PATH"
fi
#------------------ Заполнение обязательной Exif.Photo.DateTimeOriginal даты, если ее нет -------------------#
if [ "$EXIM_DATA" != "Exif.Photo.DateTimeOriginal" ] ; then exiv2 -M"set Exif.Photo.DateTimeOriginal Ascii $PHOTO_DATE $PHOTO_TIME" "$FILE_PATH" ; fi
#------- Корректировка даты файла в соотвествии с датой EXIF (exiv2 -M всегда меняет на текущую дату) -------#
if [ "$PHOTO_DATE" != "`stat -f%Sm -t'%Y:%m:%d' "$FILE_PATH"`" ] ; then exiv2 -T "$FILE_PATH" ; fi
YEAR_DATE=`echo $PHOTO_DATE | awk -F: '{ print $1 }'` ; MONTH_DATE=`echo $PHOTO_DATE | awk -F: '{ print $2 }'`
#----------------------- Секция распределения файлов по каталогам и удаления дубликатов ----------------------#
if [ `basename "$FILE_PATH"` = `basename "$FILE_PATH" | tr '[:lower:]' '[:upper:]'` ] ; then MOVE_DIR=${MOVE_DIR:-"$FILE_DIR"} ; else MOVE_DIR="$TEMP_DIR" ; fi
FILE_NAME=`echo $PHOTO_DATE | sed 's/:/-/g'`"_"`echo $PHOTO_TIME | sed 's/:/-/g'`"_"`basename "$FILE_PATH" | tr '[:lower:]' '[:upper:]'`
if [ -f "$MOVE_DIR/$YEAR_DATE/$MONTH_DATE/$FILE_NAME" ] ; then
if diff -q "$FILE_PATH" "$MOVE_DIR/$YEAR_DATE/$MONTH_DATE/$FILE_NAME"; then rm "$FILE_PATH" ; continue ; fi
if [ -f "$TEMP_DIR/$YEAR_DATE/$MONTH_DATE/$FILE_NAME" ] ; then
if diff -q "$FILE_PATH" "$TEMP_DIR/$YEAR_DATE/$MONTH_DATE/$FILE_NAME" ; then rm "$FILE_PATH" ; continue ; fi
continue ;
fi
MOVE_DIR=$TEMP_DIR
fi
#------------------------------------- Создание структуры папок гггг/мм -------------------------------------#
if ! [ -d "$MOVE_DIR/$YEAR_DATE" ] ; then mkdir -pm 777 $MOVE_DIR/$YEAR_DATE ; fi
if ! [ -d "$MOVE_DIR/$YEAR_DATE/$MONTH_DATE" ] ; then mkdir -m 777 $MOVE_DIR/$YEAR_DATE/$MONTH_DATE ; fi
#-------------------------------------- Непосредственно перенос файлов --------------------------------------#
#echo "mv -nv ($FILE_PATH) ($MOVE_DIR/$YEAR_DATE/$MONTH_DATE/$FILE_NAME)" # Перенос фотографии
mv -nv "$FILE_PATH" "$MOVE_DIR/$YEAR_DATE/$MONTH_DATE/$FILE_NAME" # Перенос фотографии
done
done
}
move_file(){
FILE_DIR=$1
#----------------------------------------- Выполнение цикла по каждому расширению -------------------------------------------#
for FILE_EXT in `echo $2 | sed 's/;/ /g'` ; do
#-------------------------- Выполнение цикла по каждому файлу с соответствующим расширением -------------------------#
find $BASE_DIR -iname "*.$FILE_EXT" | sort | while read FILE_PATH ; do
FILE_DATE=`stat -f%Sm -t'%Y:%m:%d' "$FILE_PATH"`; FILE_TIME=`stat -f%Sm -t'%H:%M:%S' "$FILE_PATH"` ; MOVE_DIR="$FILE_DIR"
YEAR_DATE=`echo $FILE_DATE | awk -F: '{ print $1 }'` ; MONTH_DATE=`echo $FILE_DATE | awk -F: '{ print $2 }'`
#---------------------- Секция распределения файлов по каталогам и удаления дубликатов ----------------------#
FILE_NAME=`echo $FILE_DATE | sed 's/:/-/g'`"_"`echo $FILE_TIME | sed 's/:/-/g'`"_"`basename "$FILE_PATH" | tr '[:lower:]' '[:upper:]'`
if [ -f "$MOVE_DIR/$YEAR_DATE/$MONTH_DATE/$FILE_NAME" ] ; then
if diff -q "$FILE_PATH" "$MOVE_DIR/$YEAR_DATE/$MONTH_DATE/$FILE_NAME"; then rm "$FILE_PATH" ; continue ; fi
if [ -f "$TEMP_DIR/$YEAR_DATE/$MONTH_DATE/$FILE_NAME" ] ; then
if diff -q "$FILE_PATH" "$TEMP_DIR/$YEAR_DATE/$MONTH_DATE/$FILE_NAME" ; then rm "$FILE_PATH" ; continue ; fi
continue ;
fi
MOVE_DIR=$TEMP_DIR
fi
#------------------------------------- Создание структуры папок гггг/мм -------------------------------------#
if ! [ -d "$MOVE_DIR/$YEAR_DATE" ] ; then mkdir -pm 777 $MOVE_DIR/$YEAR_DATE ; fi
if ! [ -d "$MOVE_DIR/$YEAR_DATE/$MONTH_DATE" ] ; then mkdir -m 777 $MOVE_DIR/$YEAR_DATE/$MONTH_DATE ; fi
#-------------------------------------- Непосредственно перенос файлов --------------------------------------#
#echo "mv -nv ($FILE_PATH) ($MOVE_DIR/$YEAR_DATE/$MONTH_DATE/$FILE_NAME)" # Перенос фотографии
mv -nv "$FILE_PATH" "$MOVE_DIR/$YEAR_DATE/$MONTH_DATE/$FILE_NAME" # Перенос фотографии
done
done
}
# Сортировка файлов с EXIF информацией
#1) РАСШИРЕНИЕ в верхнем регистре - условно необработанные файлы
move_exiv_file $SORT_DIR $FILE_EXIF $FILE_EXIF_DATA
#2) расширение(в нижнем регистре) - условно файлы после фоторедакторов
move_exiv_file $SORT_DIR `echo $FILE_EXIF | tr '[:upper:]' '[:lower:]'` $FILE_EXIF_DATA
#3) RAW файлы
move_exiv_file $DATA_DIR $FILE_RAW $FILE_RAW_DATA
#4) VIDEO файлы
move_file "/shared/photo/video" $FILE_VIDEO
#5) PICTURE файлы
#move_file "/shared/photo/picture" $FILE_PICTURE