mount -t cifs ... -o username=user,password=... 형태에서 비밀번호에 특수문자가 있으면 두 곳에서 깨진다.
첫째는 셸이다. ! 는 대화형 bash 에서 히스토리 확장으로 해석되고, $ 는 변수 치환, ` 는 명령 치환으로 해석된다. 둘째는 마운트 옵션 파서다. 옵션은 쉼표로 나뉘므로 비밀번호에 , 가 들어 있으면 그 뒤가 다른 옵션으로 읽힌다.
특수문자 문제를 근본적으로 없애고, 명령 이력과 프로세스 목록에 비밀번호가 남지 않게 한다. 실무에서는 이 방법만 쓴다.
sudo install -m 600 /dev/null /etc/cifs-credentials
sudo vi /etc/cifs-credentials
username=svc_share
password=${MASKED},w0rd$
domain=EXAMPLE
파일 안의 값은 셸을 거치지 않으므로 이스케이프하지 않고 그대로 적는다. 따옴표로 감싸면 따옴표까지 비밀번호의 일부가 되므로 감싸지 않는다.
sudo mount -t cifs //fileserver/share /mnt/share \
-o credentials=/etc/cifs-credentials,vers=3.1.1,uid=1000,gid=1000,iocharset=utf8
/etc/fstab 에도 같은 방식으로 적는다.
//fileserver/share /mnt/share cifs credentials=/etc/cifs-credentials,vers=3.1.1,_netdev,nofail 0 0
권한은 반드시 600 이고 소유자는 root 다. 그렇지 않으면 다른 사용자가 비밀번호를 읽을 수 있다.
작은따옴표로 감싸는 것이 가장 확실하다. 작은따옴표 안에서는 셸이 아무것도 해석하지 않는다.
sudo mount -t cifs //fileserver/share /mnt/share -o username=svc_share,password='${MASKED}'
다만 비밀번호에 , 가 있으면 작은따옴표로도 해결되지 않는다. 마운트 옵션 파서는 셸과 무관하게 쉼표에서 자르기 때문이다. 이 경우 자격 증명 파일 외에는 방법이 없다.
export 한 환경변수를 $VAR 로 넘기는 방식도 돌아다니는데, sudo 는 기본적으로 환경변수를 넘기지 않고 ps 에 비밀번호가 노출되므로 쓰지 않는다.