pastebin - collaborative debugging tool
rovema.kpaste.net RSS


sshnfs - ssh with nfs forwarding
Posted by Anonymous on Wed 8th Feb 2023 14:54
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 nfs://localhost/export/home/rmainz root@10.49.20.207 #
  7. #
  8. # Written by Roland Mainz <roland.mainz@nrubsig.org>
  9. #
  10.  
  11. #
  12. # parse url
  13. #
  14. # returns:
  15. # data.protocol
  16. # data.host
  17. # data.port (optional)
  18. # data.path
  19. #
  20. function parse_url
  21. {
  22.         typeset url="$2"
  23.         typeset leftover
  24.         nameref data="$1"
  25.        
  26.         leftover="${url//~(Elr)(.+?):\/\/(.+?)(?:|:([[:digit:]]+))(?:\/(.*?))?/x}"
  27.        
  28.         [[ "$leftover" == 'x' ]] || { print -u2 -f $"%s: Parser error\n" "$0" ; return 1 ; }
  29.        
  30.         #print -v .sh.match
  31.        
  32.         data.protocol="${.sh.match[1]}"
  33.         data.host="${.sh.match[2]}"
  34.         # bug: should be [[ -v .sh.match[3] }}, but ksh93u has bugs
  35.         [[ "${.sh.match[3]}" != '' ]] && integer data.port="${.sh.match[3]}"
  36.         data.path="${.sh.match[4]}"
  37.         return 0
  38. }
  39.  
  40. function parse_nfs_url
  41. {
  42.         typeset url="$2"
  43.         nameref data="$1"
  44.        
  45.         parse_url data "$url" || return 1
  46.        
  47.         [[ "${data.protocol}" == 'nfs' ]]       || { print -u2 -f $"%s: Not a NFS url\n" "$0" ; return 1 ; }
  48.         [[ "${data.host}" != '' ]]              || { print -u2 -f $"%s: NFS hostname missing\n" "$0" ; return 1 ; }
  49.         [[ "${data.path}" != '' ]]              || { print -u2 -f $"%s: NFS path missing\n" "$0" ; return 1 ; }
  50.        
  51.         if [[ ! -v data.port ]] ; then
  52.                 integer data.port=2049
  53.         fi
  54.  
  55.         return 0
  56. }
  57.  
  58.  
  59. function main
  60. {
  61.         integer i
  62.         compound c
  63.         compound c.nfs_data
  64.         integer c.forward_port=4049
  65.  
  66.         set -o xtrace
  67.         set -o nounset
  68.  
  69.         url="$1" # fixme: we should use sshnfs -o NFSURL=nfs:// ...
  70.         shift
  71.         typeset c.args=( "$@" )
  72.  
  73.         parse_nfs_url c.nfs_data "$url" || return 1
  74.  
  75.         #
  76.         # extract jump host args
  77.         #
  78.         typeset -a c.ssh_jumphost_args
  79.         for ((i=0 ; i < ${#c.args[@]} ; i++)) ; do
  80.                 if [[ "${c.args[i]}" == '-o' ]] ; then
  81.                         if [[ "${c.args[i+1]}" == ~(Elr)NFSJumphost=.+ ]] ; then
  82.                                 c.ssh_jumphost_args+=( "-J" "${c.args[i+1]#NFSJumphost=}" )
  83.                                 unset c.args[$i]
  84.                                 unset c.args[$((i+1))]
  85.                         fi
  86.                 fi
  87.         done
  88.  
  89.         # Forward NFS port from server to local machine
  90.         # Notes:
  91.         # - We use $ ssh -M ... # here as a way to terminate the port
  92.         # forwarding process later using "-O exit" without the need
  93.         # for a pid
  94.         printf $"# Please enter the password for NFS server (%s)\n" \
  95.                 "root@${c.nfs_data.host}"
  96.         ssh \
  97.                 -L "${c.forward_port}:localhost:${c.nfs_data.port}" \
  98.                 -M -S "$PWD/ssh-control-socket" \
  99.                 -N \
  100.                 -f -o ExitOnForwardFailure=yes \
  101.                 "${c.ssh_jumphost_args[@]}" \
  102.                 "root@${c.nfs_data.host}"
  103.         (( $? == 0 )) || { printf $"%s: NFS forwarding ssh failed with error code %d\n" "$0" $? ; return 1 ; }
  104.         #ssh -S "$PWD/ssh-control-socket" -O 'check' "root@${c.nfs_data.host}"
  105.  
  106.         printf $"# Use this to mount the directory:\n"
  107.         printf $"# $ mkdir /mnt_nfs\n"
  108.         printf $"# mount -vvv -t nfs -o vers=4,port=%d localhost:/%s /mnt_nfs\n" \
  109.                 3049 \
  110.                 "${c.nfs_data.path}"
  111.  
  112.         ssh -R "3049:localhost:${c.forward_port}" "${c.args[@]}" # root@10.49.20.207
  113.  
  114.         ssh -S "$PWD/ssh-control-socket" -O 'exit' "root@${c.nfs_data.host}"
  115.         wait
  116.  
  117.         return 0
  118. }
  119.  
  120. main "$@"
  121.  
  122. # 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