Skip to Content

How to Mount Amazon EFS on Windows

…for no particular reason.

Published on

Random characters surrounding the "\\wsl$\efs" file explorer path.

First of all, why would you want to mount EFS on Windows? My initial idea was to have a Kirby CMS(opens in new tab) site there and easily manage it from the comfort of my PC. However, after seeing how complex it seemed to turn out, I did it just for fun — to figure out if it's even possible. I wanted to see how trippy it would feel to update files in EFS via the Windows File Explorer.

The Regular Way

The first thing that comes to mind is to just:

  1. Install the NFS utilities package:

    sudo apt update
    sudo apt install nfs-common

    You can check this guide for mounting NFS on Ubuntu(opens in new tab).

  2. Mount EFS as it's suggested in the EFS console:

    sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport fs-003f3467bf1e15b13.efs.us-east-1.amazonaws.com:/ efs

However, that would turn out unsuccessful:

mount.nfs4: Failed to resolve server fs-003f3467bf1e15b13.efs.us-east-1.amazonaws.com: Name or service not known

This happens because the filesystem is not accessible outside our VPC on a network level, so the DNS resolution fails.

Making EFS Public

If the problem is that EFS is not publicly accessible, couldn't we just make it public?

You can allocate an Elastic IP, but when you attempt to attach it to the network interface of your EFS filesystem, you'd get the following error:

Failed to associate address with eni-0fa8cf69d68b7bb01: You do not have permission to access the specified resource.

"Association details" form in the AWS EC2 console with a permission error at the top.

This makes no sense, especially if you're the root user of the account, so I asked about this in the AWS forum(opens in new tab). The explanation was really quite simple:

Associating an Elastic IP (or Public IP) with EFS isn't supported.

You could use AWS Client VPN(opens in new tab) and probably get this running a lot easier, but, well, it costs $0.10 per hour(opens in new tab) just for having it running. Paying over $70 per month certainly wasn't viable for me, so I kept searching for other ways.

Setting up a Jump Host

We can't make EFS public, but luckily, SSH tunnelling(opens in new tab) is a thing and we can still expose it to the outside.

Creating a Tunnel

Spin up a new EC2 instance in the same VPC as your EFS and add your WSL SSH key to it. Once you have SSH access to the EC2 instance, change the IP and hostname in the following command accordingly and run it in WSL:

ssh -fNL 1234:172.31.43.109:2049 [email protected]

In this case, 172.31.43.109 is the IP of EFS and ec2-54-147-161-134.compute-1.amazonaws.com is the hostname of the EC2 instance. We map the local port 1234 of WSL to the remote port 2049 on EFS, which is the default port for NFS connections(opens in new tab), and we use the ec2-user on the EC2 instance as the bridge to do so.

For more information on the individual command flags (-fNL), check the SSH manual(opens in new tab).

Inside WSL, use netstat(opens in new tab) to verify that the SSH tunnel works:

netstat -plant

If you see something like this, it works:

Proto  Local Address   Foreign Address  State   PID/Program name
tcp    127.0.0.1:1234  0.0.0.0:*        LISTEN  318/ssh

Mounting EFS

Create the directory where you want to mount EFS, then mount(opens in new tab) it:

mkdir efs
sudo mount -t nfs4 -o port=1234 localhost:/ efs

As you can see, we use the port option, and we essentially mount localhost:1234 to the efs directory. But because port 1234 is being forwarded to EFS over our SSH tunnel, we've actually mounted EFS itself!

Fixing Permissions

At this point, you've successfully mounted EFS, but you wouldn't be able to actually create files:

touch efs/test.txt
touch: cannot touch 'efs/test.txt': Permission denied

That's because the default onwer of the filesystem has POSIX(opens in new tab) user ID 0, which is the root user, meaning that you can only create files using sudo.

To fix that, you'd normally use an EFS access point(opens in new tab). With it, you mount EFS in such a way that all filesystem operations are done using the POSIX IDs as specified by the access point, rather than the OS. This is how you'd do it:

sudo mount -t efs -o tls,accesspoint=fsap-0a18c15383236b5d3 fs-003f3467bf1e15b13:/ efs

Notice, however, that the mount type is now efs, rather than nfs4, and we run into networking problems once again:

Failed to resolve "fs-003f3467bf1e15b13.efs.us-east-1.amazonaws.com" - check that your file system ID is correct, and ensure that the VPC has an EFS mount target for this file system ID.

We have to use our SSH tunnelling workaround here as well, but unfortunately, I asked about this in the AWS forum(opens in new tab) and it doesn't seem to be currently possible.

Since we can't use an access point to assume the correct user, we can simply change the owner of the files:

sudo chown dodov:dodov efs -R

Now, you should be able to run explorer.exe efs and use EFS as any other folder on your PC:

Windows Explorer window with the mounted EFS filesystem opened.
EFS as seen in Windows Explorer

Shutting Down

To unmount EFS, use umount(opens in new tab) (notice that there's no "n" in the name, i.e. it's not unmount):

sudo umount efs

To end your SSH tunnel, you can list all running processes:

ps aux
USER   PID  …  COMMAND
root     9  …  /init
dodov   10  …  -bash
dodov  123  …  ssh -fNL 1234:172.31.43.109:2049 ec2-user@ec2-54…
dodov  146  …  ps aux

…then kill the ssh process using its PID:

kill 123

Conclusion

Mounting on Windows might not be a very practical use case for EFS, but I guess it can be useful in some obscure situations. Using a jump server to do that is surely not ideal, but it can be a good budget option, compared to AWS VPN. At the very least, it's a good opportunity to experiment with SSH tunnelling.