pastebin - collaborative debugging tool
rovema.kpaste.net RSS


sshnfs - ssh with nfs forwarding
Posted by Anonymous on Fri 10th Feb 2023 11:58
raw | new post
view followups (newest first): sshnfs - ssh with nfs forwarding by Anonymous
modification of post by Anonymous (view diff)

  1. #!/usr/bin/ksh93
  2. #
  3. # sshnfs - remote login client with NFSv4 forwarding
  4. #
  5. # Example usage:
  6. # $ ksh sshnfs.ksh -o NFSURL=nfs://localhost/export/home/rmainz root@10.49.20.207 #
  7. # $ ksh sshnfs.ksh -o NFSURL=nfs://localhost/export/home/rmainz -o NFSJumphost=derfwpc5131 root@10.49.20.207
  8. #
  9. # Written by Roland Mainz <roland.mainz@nrubsig.org>
  10. #
  11.  
  12. #
  13. # parse url
  14. #
  15. # returns:
  16. # data.protocol
  17. # data.host
  18. # data.port (optional)
  19. # data.path
  20. #
  21. function parse_url
  22. {
  23.         typeset url="$2"
  24.         typeset leftover
  25.         nameref data="$1"
  26.        
  27.         # ~(E) is POSIX extended regular expression matching (instead of
  28.         # shell pattern)
  29.         leftover="${url//~(Elr)(.+?):\/\/(.+?)(?:|:([[:digit:]]+))(?:\/(.*?))?/x}"
  30.        
  31.         # All parsed data should be captured via eregex in .sh.match - if
  32.         # there is anything left then the input string did not properly match
  33.         # the eregex
  34.         [[ "$leftover" == 'x' ]] || { print -u2 -f $"%s: Parser error\n" "$0" ; return 1 ; }
  35.  
  36.         data.protocol="${.sh.match[1]}"
  37.         data.host="${.sh.match[2]}"
  38.         # bug: should be [[ -v .sh.match[3] }}, but ksh93u has bugs
  39.         [[ "${.sh.match[3]}" != '' ]] && integer data.port="${.sh.match[3]}"
  40.         data.path="${.sh.match[4]}"
  41.         return 0
  42. }
  43.  
  44. function parse_nfs_url
  45. {
  46.         typeset url="$2"
  47.         nameref data="$1"
  48.        
  49.         parse_url data "$url" || return 1
  50.        
  51.         [[ "${data.protocol}" == 'nfs' ]]       || { print -u2 -f $"%s: Not a NFS url\n" "$0" ; return 1 ; }
  52.         [[ "${data.host}" != '' ]]              || { print -u2 -f $"%s: NFS hostname missing\n" "$0" ; return 1 ; }
  53.         [[ "${data.path}" != '' ]]              || { print -u2 -f $"%s: NFS path missing\n" "$0" ; return 1 ; }
  54.        
  55.         if [[ ! -v data.port ]] ; then
  56.                 integer data.port=2049
  57.         fi
  58.  
  59.         return 0
  60. }
  61.  
  62.  
  63. function main
  64. {
  65.         integer i
  66.         compound c
  67.         compound c.nfs_data
  68.         integer c.forward_port=34049
  69.         integer retval
  70.  
  71.         #set -o xtrace
  72.         set -o nounset
  73.  
  74.         typeset c.args=( "$@" )
  75.  
  76.         for ((i=0 ; i < ${#c.args[@]} ; i++)) ; do
  77.                 if [[ "${c.args[i]}" == '-o' ]] ; then
  78.                         case "${c.args[i+1]-}" in
  79.                                 'NFSURL='*)
  80.                                         unset c.nfs_data
  81.                                         typeset c.url="${c.args[i+1]#NFSURL=}"
  82.                                         parse_nfs_url c.nfs_data "${c.url}" || return 1
  83.                                         unset c.args[$i] c.args[$((i+1))]
  84.                                         ((i++))
  85.                                         ;;
  86.                                 'NFSJumphost='*)
  87.                                         [[ ! -v c.ssh_jumphost_args ]] && typeset -a c.ssh_jumphost_args
  88.                                         c.ssh_jumphost_args+=( "-J" "${c.args[i+1]#NFSJumphost=}" )
  89.                                         unset c.args[$i] c.args[$((i+1))]
  90.                                         ((i++))
  91.                                         ;;
  92.                         esac
  93.                 fi
  94.         done
  95.  
  96.         # bug: should be [[ -v c.nfs_data ]], but ksh93u has bugs
  97.         if [[ -v c.nfs_data.host ]] ; then
  98.                 # Forward NFS port from server to local machine
  99.                 # Notes:
  100.                 # - We use $ ssh -M ... # here as a way to terminate the port
  101.                 # forwarding process later using "-O exit" without the need
  102.                 # for a pid
  103.                 printf $"# Please enter the password for NFS server (%s)\n" \
  104.                         "root@${c.nfs_data.host}"
  105.                 ssh \
  106.                         -L "${c.forward_port}:localhost:${c.nfs_data.port}" \
  107.                         -M -S "$PWD/ssh-control-socket" \
  108.                         -N \
  109.                         -f -o ExitOnForwardFailure=yes \
  110.                         "${c.ssh_jumphost_args[@]}" \
  111.                         "root@${c.nfs_data.host}"
  112.                 if (( $? != 0 )) ; then
  113.                         printf $"%s: NFS forwarding ssh failed with error code %d\n" "$0" $?
  114.                         return 1
  115.                 fi
  116.                 #ssh -S "$PWD/ssh-control-socket" -O 'check' "root@${c.nfs_data.host}"
  117.  
  118.                 printf $"# Use this to mount the directory:\n"
  119.                 printf $"# $ mkdir /mnt_nfs\n"
  120.                 printf $"# $ mount -vvv -t nfs -o vers=4,port=%d localhost:/%s /mnt_nfs\n" \
  121.                         33049 \
  122.                         "${c.nfs_data.path}"
  123.  
  124.                 # add NFS forwarding options to main ssh argument list
  125.                 c.args=( "-R" "33049:localhost:${c.forward_port}" "${c.args[@]}" )
  126.         fi
  127.  
  128.         ssh "${c.args[@]}" ; (( retval=$? ))
  129.  
  130.         if [[ -v c.nfs_data.host ]] ; then
  131.                 ssh -S "$PWD/ssh-control-socket" -O 'exit' "root@${c.nfs_data.host}"
  132.         fi
  133.  
  134.         wait
  135.  
  136.         return $retval
  137. }
  138.  
  139. main "$@"
  140.  
  141. # EOF.

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at