245 lines
6.4 KiB
Bash
Executable File
245 lines
6.4 KiB
Bash
Executable File
#!/bin/sh /etc/rc.common
|
|
START=45
|
|
STOP=99
|
|
EXTRA_COMMANDS="firewall restart"
|
|
APP="nfs"
|
|
|
|
check_nfsd() {
|
|
pidof nfsd &>/dev/null && return 0
|
|
return 1
|
|
}
|
|
|
|
get_lan_wan_ip() {
|
|
[ -z "$1" ] && return 1
|
|
ip=''
|
|
. /lib/functions/network.sh>/dev/null
|
|
network_get_ipaddr ip $1>/dev/null && echo "$ip"
|
|
}
|
|
|
|
iptables_init() {
|
|
INPUT="INPUT"
|
|
iptables -t filter --list zone_wan_input &>/dev/null && INPUT="zone_wan_input"
|
|
PREROUTING="PREROUTING"
|
|
iptables -t nat --list zone_wan_prerouting &>/dev/null && PREROUTING="zone_wan_prerouting"
|
|
[ -z "$LAN_IP" ] && {
|
|
LAN_IP=$(get_lan_wan_ip 'lan')
|
|
[ -z "$LAN_IP" ] && return 1
|
|
}
|
|
if [ "$external_access" = '1' ]; then
|
|
RULES_NAT="*nat
|
|
-A $PREROUTING -p udp -m udp --dport 111 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:111
|
|
-A $PREROUTING -p tcp -m tcp --dport 111 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:111
|
|
-A $PREROUTING -p udp -m udp --dport 2049 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:2049
|
|
-A $PREROUTING -p tcp -m tcp --dport 2049 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:2049
|
|
-A $PREROUTING -p udp -m udp --dport 32777 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:32777
|
|
-A $PREROUTING -p tcp -m tcp --dport 32777 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:32777
|
|
-A $PREROUTING -p udp -m udp --dport 32780 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:32780
|
|
-A $PREROUTING -p tcp -m tcp --dport 32780 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:32780
|
|
COMMIT"
|
|
else
|
|
SOURCE="-s ${LAN_IP%.*}.0/24 "
|
|
fi
|
|
RULES_FILTER="*filter
|
|
-A $INPUT ${SOURCE}-p udp -m udp --dport 111:2049 -m comment --comment \"NFS\" -j ACCEPT
|
|
-A $INPUT ${SOURCE}-p tcp -m tcp --dport 111:2049 -m comment --comment \"NFS\" -j ACCEPT
|
|
-A $INPUT ${SOURCE}-p udp -m udp --dport 32777:32780 -m comment --comment \"NFS\" -j ACCEPT
|
|
-A $INPUT ${SOURCE}-p tcp -m tcp --dport 32777:32780 -m comment --comment \"NFS\" -j ACCEPT
|
|
COMMIT"
|
|
return 0
|
|
}
|
|
|
|
iptables_run() {
|
|
[ -z "$1" -o -z "$2" ] && return 1
|
|
RUN_RUNLES=$(echo -e "$1"|grep -Eo '[-][A].*')
|
|
[ "$3" = '-D' ] && RUN_RUNLES=$(echo -e "$RUN_RUNLES"|sed -E 's/^-[AI]/-D/')
|
|
while read RULE
|
|
do
|
|
eval "iptables -t $2 $RULE"
|
|
done <<-EOF
|
|
$(echo -e "$RUN_RUNLES")
|
|
EOF
|
|
}
|
|
|
|
iptables_flush() {
|
|
iptables_init || return 1
|
|
iptables-restore <<-EOF || {
|
|
$(echo -e "$( iptables-save)" | grep -v 'NFS')
|
|
EOF
|
|
iptables_run "$RULES_FILTER" "filter" "-D" &>/dev/null
|
|
iptables_run "$RULES_NAT" "nat" "-D" &>/dev/null
|
|
}
|
|
return $?
|
|
}
|
|
|
|
iptables_restore() {
|
|
iptables_init || return 1
|
|
iptables-restore -n <<-EOF || {
|
|
$RULES_FILTER
|
|
$RULES_NAT
|
|
EOF
|
|
iptables_run "$RULES_FILTER" "filter" "-A"
|
|
[ "$external_access" = '1' ] && iptables_run "$RULES_NAT" "nat" "-A"
|
|
}
|
|
return $?
|
|
}
|
|
|
|
nfs_general() {
|
|
config_get external_access "$1" external_access '0'
|
|
}
|
|
|
|
nfs_share() {
|
|
[ -z "$1" ] && return 1
|
|
config_get enabled "$1" enabled
|
|
[ "$enabled" = '1' ] || return 1
|
|
config_get path "$1" path
|
|
[ -d "$path" ] || return 1
|
|
config_get clients "$1" clients
|
|
[ -z "$clients" ] && return 1
|
|
config_get permission "$1" permission '0'
|
|
case $permission in
|
|
1)
|
|
NFS_PERMISSION='no_root_squash'
|
|
;;
|
|
2)
|
|
NFS_PERMISSION='no_root_squash,fsid=0'
|
|
;;
|
|
*)
|
|
NFS_PERMISSION='all_squash'
|
|
;;
|
|
esac
|
|
config_get read_only "$1" read_only '0'
|
|
NFS_OPERATION="rw"
|
|
[ $read_only = '1' ] && NFS_OPERATION="ro"
|
|
NFS_INSECURE=""
|
|
config_get insecure "$1" insecure '1'
|
|
[ $insecure = '1' ] && NFS_INSECURE=",insecure"
|
|
[ -z "$NFS_SHARE_ALL" ] || {
|
|
FIND_NFS=$(echo -e "$NFS_SHARE_ALL"|grep -i "^$path ")
|
|
}
|
|
if [ -z "$FIND_NFS" ]; then
|
|
NFS_SHARE_ALL=$([ -z "$NFS_SHARE_ALL" ] || echo "$NFS_SHARE_ALL\n")"$path $clients($NFS_OPERATION,no_subtree_check,$NFS_PERMISSION,async$NFS_INSECURE)"
|
|
else
|
|
NFS_SHARE_ALL=$(echo -e "$NFS_SHARE_ALL"|grep -iv "^$path ")
|
|
NFS_SHARE_ALL=$([ -z "$NFS_SHARE_ALL" ] || echo "$NFS_SHARE_ALL\n")"$FIND_NFS $clients($NFS_OPERATION,no_subtree_check,$NFS_PERMISSION,async$NFS_INSECURE)"
|
|
fi
|
|
}
|
|
|
|
nfs_share_start() {
|
|
NFS_EXPORTS=$(cat /etc/exports)
|
|
if check_nfsd; then
|
|
if [ -z "$NFS_SHARE_ALL" ]; then
|
|
echo -e "$NFS_SHARE_ALL">/etc/exports
|
|
nfs_share_stop
|
|
return 1
|
|
else
|
|
[ "$(echo -e $NFS_EXPORTS)" = "$(echo -e $NFS_SHARE_ALL)" ] || {
|
|
echo -e "$NFS_SHARE_ALL">/etc/exports
|
|
/usr/sbin/exportfs -ar
|
|
}
|
|
fi
|
|
else
|
|
echo -e "$NFS_SHARE_ALL">/etc/exports
|
|
/etc/init.d/portmap start &>/dev/null
|
|
/etc/init.d/nfsd start &>/dev/null
|
|
fi
|
|
iptables_flush
|
|
iptables_restore
|
|
}
|
|
|
|
nfs_share_stop() {
|
|
iptables_flush
|
|
/etc/init.d/nfsd stop &>/dev/null
|
|
/etc/init.d/portmap stop &>/dev/null
|
|
}
|
|
|
|
get_mounted_nfs() {
|
|
[ -z "$MOUNTED_ALL" ] && {
|
|
MOUNTED_ALL=$(mount)
|
|
MOUNTED_NFS_ALL=$(echo -e "$MOUNTED_ALL"|grep "type\s\+nfs\s")
|
|
}
|
|
}
|
|
|
|
create_mount_dir() {
|
|
if [ -d "$1" ]; then
|
|
[ -z $(ls $"$1" 2>/dev/null) ] && return 0
|
|
return 1
|
|
else
|
|
mkdir "$1"
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
nfs_mount() {
|
|
[ -z "$1" ] && return 1
|
|
config_get enabled "$1" enabled
|
|
[ "$enabled" = '1' ] || return 1
|
|
config_get host "$1" host
|
|
[ -z "$host" ] && return 1
|
|
config_get path "$1" path
|
|
[ -z "$path" ] && return 1
|
|
config_get mount_on "$1" mount_on
|
|
[ -z "$mount_on" ] && return 1
|
|
config_get read_only "$1" read_only '0'
|
|
MOUNT_OPERATION="rw"
|
|
[ $read_only = '1' ] && MOUNT_OPERATION="ro"
|
|
get_mounted_nfs
|
|
NFS_MOUNTING=$([ -z "$NFS_MOUNTING" ] || echo "$NFS_MOUNTING\n")"$host:$path"
|
|
NFS_MOUNT_MATCH=$(echo -e "$MOUNTED_NFS_ALL"|grep "^$host:$path")
|
|
if [ -z "$NFS_MOUNT_MATCH" ]; then
|
|
create_mount_dir "$mount_on" && mount -t nfs -o $MOUNT_OPERATION -o nolock "$host:$path" "$mount_on"
|
|
else
|
|
echo "$NFS_MOUNT_MATCH"|grep "$mount_on\s\+type\s\+nfs\s\+($MOUNT_OPERATION" 2>/dev/null && return 1
|
|
umount -fr "$mount_on" && mount -t nfs -o $MOUNT_OPERATION -o nolock "$host:$path" "$mount_on"
|
|
fi
|
|
}
|
|
|
|
nfs_mount_clean() {
|
|
MOUNTED_ALL=''
|
|
get_mounted_nfs
|
|
echo -e "$MOUNTED_NFS_ALL"|while read NFS_SHARED
|
|
do
|
|
echo -e "$NFS_MOUNTING"|grep -x "${NFS_SHARED% on *}" 2>/dev/null || {
|
|
NFS_SHARED_MOUNT="${NFS_SHARED##* on }"
|
|
NFS_SHARED_MOUNT="${NFS_SHARED_MOUNT%% type*}"
|
|
umount -fr "$NFS_SHARED_MOUNT" && rm -r "$NFS_SHARED_MOUNT"
|
|
}
|
|
done
|
|
}
|
|
|
|
config_cb() {
|
|
local cfg="$CONFIG_SECTION"
|
|
config_get configname "$cfg" TYPE
|
|
case "$configname" in
|
|
general)
|
|
nfs_general "$cfg"
|
|
;;
|
|
share)
|
|
nfs_share "$cfg"
|
|
;;
|
|
mount)
|
|
nfs_mount "$cfg"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
start() {
|
|
config_load "$APP"
|
|
nfs_share_start
|
|
nfs_mount_clean
|
|
}
|
|
|
|
stop() {
|
|
nfs_mount_clean
|
|
nfs_share_stop
|
|
}
|
|
|
|
restart() {
|
|
start
|
|
}
|
|
|
|
firewall() {
|
|
config_load "$APP"
|
|
iptables_restore
|
|
}
|
|
|