Linux 之 利用Google Authenticator實現用戶雙因素認證


一、介紹:什么是雙因素認證

  雙因素身份認證就是通過你所知道再加上你所能擁有的這二個要素組合到一起才能發揮作用的身份認證系統。雙因素認證是一種采用時間同步技術的系統,采用了基於時間、事件和密鑰三變量而產生的一次性密碼來代替傳統的靜態密碼。每個動態密碼卡都有一個唯一的密鑰,該密鑰同時存放在服務器端,每次認證時動態密碼卡與服務器分別根據同樣的密鑰,同樣的隨機參數(時間、事件)和同樣的算法計算了認證的動態密碼,從而確保密碼的一致性,從而實現了用戶的認證。

  說白了,就像我們幾年前去銀行辦卡送的口令牌,以及網易游戲中的將軍令,在你使用網銀或登陸游戲時會再讓你輸入動態口令的。

二、產品分類

  市面上有基於硬件的,也有基於軟件的產品,具體可以另搜啊,本人喜歡開源的東東,並找到了Google開源的二次認證系統Google Authenticator OpenSource,可以利用智能手機生產30秒動態口令配合登陸linux系統,該驗證器提供了一個六位數的一次性密碼。目前iosAndroid 都有客戶端供於下載。

三、目的

  1.實現登陸linux 服務器時,先輸入動態口令,認證成功后,在下一步輸入用戶密碼。如果口令失敗,不會進行下一步的本地密碼認證。

  2.部署完成后,即使服務器不能上網,或者手機客戶端不能上網,整個二步驗證系統還是可以正常運行的。

四、基礎+部署步驟

4.1 基本環境:

  OS:Centos 7 (最小化安裝)

  IP :192.168.1.125

4.2 所需軟件:
chrony
pam-devel
libpam-google-authenticator-1.0-source.tar.bz2
qrencode-3.4.4
libpng、libpng-devel

4.3 部署

4.3.1 安裝開發者工具,主要后續需要編譯,這有gcc等編譯器,以及需要用到的庫

[root@test ~]# yum groupinstall "Development Tools" -y

4.3.2 安裝pam 開發包

[root@test ~]# yum install pam-devel -y

4.3.3 安裝chrony 軟件,因為動態口令再驗證時用到了時間,所以要保持時間上的一致性。簡單說下chrony:chrony 是網絡時間協議的(NTP)的另一種實現,與網絡時間協議后台程序(ntpd)不同,它可以更快地更准確地同步系統始終。如果要使用ntp 需要單獨安裝。

下面是安裝並修改chronyd的配置文件添加(大概是第6行后)鍋內比較好用的ntp服務器:官網

[root@test ~]# yum install chrony -y
[root@test ~]# vim /etc/chrony.conf 
…
server 2.cn.pool.ntp.org iburst

重啟服務並使用命令查看同步(注:202.118.1.130就是我們上一步添加的那個ntp server)

[root@test ~]# systemctl restart chronyd
[root@test ~]# chronyc sources
210 Number of sources = 3
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^* 202.118.1.130                 2   6    17    54    -58us[ +132us] +/-   85ms
^+ news.neu.edu.cn               2   6    17    54   +542us[ +732us] +/-   89ms
^- dns1.synet.edu.cn             2   6   251    46    +25ms[  +25ms] +/-   60ms

如果時區不對的話,可以拷貝你當前地區所在地的時區到系統運行的時區,如下:

cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

4.3.4 現在去google 的git hub 上下載源碼文件

[root@test ~]# git clone https://github.com/google/google-authenticator.git
正克隆到 'google-authenticator'...
remote: Counting objects: 1415, done.
remote: Total 1415 (delta 0), reused 0 (delta 0), pack-reused 1415
接收對象中: 100% (1415/1415), 2.33 MiB | 86.00 KiB/s, done.
處理 delta 中: 100% (741/741), done.

進入剛剛git下載的目錄中,進行安裝

[root@test ~]# cd google-authenticator/libpam/

 

2016-12-10日 更正記錄:由於谷歌 github上將libpam 認證模塊放到一個單獨項目內,4.3.4步驟已過時,下面是新的下載源碼方式:

[root@test ~]# git clone https://github.com/google/google-authenticator-libpam.git

 

進入到該目錄中進行面的編譯安裝。

下面是編譯安裝

[root@test libpam]# ./bootstrap.sh 
libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, `build'.
libtoolize: copying file `build/ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `build'.
libtoolize: copying file `build/libtool.m4'
libtoolize: copying file `build/ltoptions.m4'
libtoolize: copying file `build/ltsugar.m4'
libtoolize: copying file `build/ltversion.m4'
libtoolize: copying file `build/lt~obsolete.m4'
configure.ac:11: installing 'build/config.guess'
configure.ac:11: installing 'build/config.sub'
configure.ac:8: installing 'build/install-sh'
configure.ac:8: installing 'build/missing'
Makefile.am: installing 'build/depcomp'
parallel-tests: installing 'build/test-driver'
[root@test libpam]# ./configure 
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking minix/config.h usability... no
checking minix/config.h presence... no
checking for minix/config.h... no
checking whether it is safe to define __EXTENSIONS__... yes
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking whether make supports nested variables... yes
checking dependency style of gcc... gcc3
checking whether to enable maintainer-specific portions of Makefiles... yes
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking how to print strings... printf
checking for a sed that does not truncate output... /usr/bin/sed
checking for fgrep... /usr/bin/grep -F
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking how to convert x86_64-unknown-linux-gnu file names to x86_64-unknown-linux-gnu format... func_convert_file_noop
checking how to convert x86_64-unknown-linux-gnu file names to toolchain format... func_convert_file_noop
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for ar... ar
checking for archiver @FILE support... @
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from gcc object... ok
checking for sysroot... no
checking for mt... no
checking if : is a manifest tool... no
checking for dlfcn.h... yes
checking for objdir... .libs
checking if gcc supports -fno-rtti -fno-exceptions... no
checking for gcc option to produce PIC... -fPIC -DPIC
checking if gcc PIC flag -fPIC -DPIC works... yes
checking if gcc static flag -static works... no
checking if gcc supports -c -o file.o... yes
checking if gcc supports -c -o file.o... (cached) yes
checking whether the gcc linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
checking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to accept ISO C89... (cached) none needed
checking for gcc option to accept ISO C99... -std=gnu99
checking for gcc -std=gnu99 option to accept ISO Standard C... (cached) -std=gnu99
checking sys/fsuid.h usability... yes
checking sys/fsuid.h presence... yes
checking for sys/fsuid.h... yes
checking for setfsuid... yes
checking for security/pam_appl.h... yes
checking for security/pam_modules.h... yes
checking for pam_get_user in -lpam... yes
checking whether certain PAM functions require const arguments... yes
checking for library containing dlopen... -ldl
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating contrib/rpm.spec
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing libtool commands

  google-authenticator version 1.01
  Prefix.........: /usr/local
  Debug Build....: 
  C Compiler.....: gcc -std=gnu99 -g -O2 
  Linker.........: /usr/bin/ld -m elf_x86_64  -ldl 

[root@test libpam]# make && make install
make  all-am
make[1]: 進入目錄“/root/google-authenticator/libpam”
/bin/sh ./libtool  --tag=CC   --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I.     -g -O2 -MT src/pam_google_authenticator_la-pam_google_authenticator.lo -MD -MP -MF src/.deps/pam_google_authenticator_la-pam_google_authenticator.Tpo -c -o src/pam_google_authenticator_la-pam_google_authenticator.lo `test -f 'src/pam_google_authenticator.c' || echo './'`src/pam_google_authenticator.c
libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -g -O2 -MT src/pam_google_authenticator_la-pam_google_authenticator.lo -MD -MP -MF src/.deps/pam_google_authenticator_la-pam_google_authenticator.Tpo -c src/pam_google_authenticator.c  -fPIC -DPIC -o src/.libs/pam_google_authenticator_la-pam_google_authenticator.o
libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -g -O2 -MT src/pam_google_authenticator_la-pam_google_authenticator.lo -MD -MP -MF src/.deps/pam_google_authenticator_la-pam_google_authenticator.Tpo -c src/pam_google_authenticator.c -o src/pam_google_authenticator_la-pam_google_authenticator.o >/dev/null 2>&1
mv -f src/.deps/pam_google_authenticator_la-pam_google_authenticator.Tpo src/.deps/pam_google_authenticator_la-pam_google_authenticator.Plo
/bin/sh ./libtool  --tag=CC   --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I.     -g -O2 -MT src/pam_google_authenticator_la-base32.lo -MD -MP -MF src/.deps/pam_google_authenticator_la-base32.Tpo -c -o src/pam_google_authenticator_la-base32.lo `test -f 'src/base32.c' || echo './'`src/base32.c
libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -g -O2 -MT src/pam_google_authenticator_la-base32.lo -MD -MP -MF src/.deps/pam_google_authenticator_la-base32.Tpo -c src/base32.c  -fPIC -DPIC -o src/.libs/pam_google_authenticator_la-base32.o
libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -g -O2 -MT src/pam_google_authenticator_la-base32.lo -MD -MP -MF src/.deps/pam_google_authenticator_la-base32.Tpo -c src/base32.c -o src/pam_google_authenticator_la-base32.o >/dev/null 2>&1
mv -f src/.deps/pam_google_authenticator_la-base32.Tpo src/.deps/pam_google_authenticator_la-base32.Plo
/bin/sh ./libtool  --tag=CC   --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I.     -g -O2 -MT src/pam_google_authenticator_la-hmac.lo -MD -MP -MF src/.deps/pam_google_authenticator_la-hmac.Tpo -c -o src/pam_google_authenticator_la-hmac.lo `test -f 'src/hmac.c' || echo './'`src/hmac.c
libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -g -O2 -MT src/pam_google_authenticator_la-hmac.lo -MD -MP -MF src/.deps/pam_google_authenticator_la-hmac.Tpo -c src/hmac.c  -fPIC -DPIC -o src/.libs/pam_google_authenticator_la-hmac.o
libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -g -O2 -MT src/pam_google_authenticator_la-hmac.lo -MD -MP -MF src/.deps/pam_google_authenticator_la-hmac.Tpo -c src/hmac.c -o src/pam_google_authenticator_la-hmac.o >/dev/null 2>&1
mv -f src/.deps/pam_google_authenticator_la-hmac.Tpo src/.deps/pam_google_authenticator_la-hmac.Plo
/bin/sh ./libtool  --tag=CC   --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I.     -g -O2 -MT src/pam_google_authenticator_la-sha1.lo -MD -MP -MF src/.deps/pam_google_authenticator_la-sha1.Tpo -c -o src/pam_google_authenticator_la-sha1.lo `test -f 'src/sha1.c' || echo './'`src/sha1.c
libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -g -O2 -MT src/pam_google_authenticator_la-sha1.lo -MD -MP -MF src/.deps/pam_google_authenticator_la-sha1.Tpo -c src/sha1.c  -fPIC -DPIC -o src/.libs/pam_google_authenticator_la-sha1.o
libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -g -O2 -MT src/pam_google_authenticator_la-sha1.lo -MD -MP -MF src/.deps/pam_google_authenticator_la-sha1.Tpo -c src/sha1.c -o src/pam_google_authenticator_la-sha1.o >/dev/null 2>&1
mv -f src/.deps/pam_google_authenticator_la-sha1.Tpo src/.deps/pam_google_authenticator_la-sha1.Plo
/bin/sh ./libtool  --tag=CC   --mode=link gcc -std=gnu99  -g -O2  -avoid-version -module -shared -export-dynamic -export-symbols-regex "pam_sm_(setcred|open_session|authenticate)"  -o pam_google_authenticator.la -rpath /usr/local/lib/security src/pam_google_authenticator_la-pam_google_authenticator.lo src/pam_google_authenticator_la-base32.lo src/pam_google_authenticator_la-hmac.lo src/pam_google_authenticator_la-sha1.lo -lpam -ldl 
libtool: link: /usr/bin/nm -B  src/.libs/pam_google_authenticator_la-pam_google_authenticator.o src/.libs/pam_google_authenticator_la-base32.o src/.libs/pam_google_authenticator_la-hmac.o src/.libs/pam_google_authenticator_la-sha1.o   | sed -n -e 's/^.*[     ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[     ][     ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p' | sed '/ __gnu_lto/d' | /usr/bin/sed 's/.* //' | sort | uniq > .libs/pam_google_authenticator.exp
libtool: link: /usr/bin/grep -E -e "pam_sm_(setcred|open_session|authenticate)" ".libs/pam_google_authenticator.exp" > ".libs/pam_google_authenticator.expT"
libtool: link: mv -f ".libs/pam_google_authenticator.expT" ".libs/pam_google_authenticator.exp"
libtool: link: echo "{ global:" > .libs/pam_google_authenticator.ver
libtool: link:  cat .libs/pam_google_authenticator.exp | sed -e "s/\(.*\)/\1;/" >> .libs/pam_google_authenticator.ver
libtool: link:  echo "local: *; };" >> .libs/pam_google_authenticator.ver
libtool: link:  gcc -shared  -fPIC -DPIC  src/.libs/pam_google_authenticator_la-pam_google_authenticator.o src/.libs/pam_google_authenticator_la-base32.o src/.libs/pam_google_authenticator_la-hmac.o src/.libs/pam_google_authenticator_la-sha1.o   -lpam -ldl  -O2   -Wl,-soname -Wl,pam_google_authenticator.so -Wl,-version-script -Wl,.libs/pam_google_authenticator.ver -o .libs/pam_google_authenticator.so
libtool: link: ( cd ".libs" && rm -f "pam_google_authenticator.la" && ln -s "../pam_google_authenticator.la" "pam_google_authenticator.la" )
depbase=`echo src/google-authenticator.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
gcc -std=gnu99 -DHAVE_CONFIG_H -I.     -g -O2 -MT src/google-authenticator.o -MD -MP -MF $depbase.Tpo -c -o src/google-authenticator.o src/google-authenticator.c &&\
mv -f $depbase.Tpo $depbase.Po
depbase=`echo src/base32.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
gcc -std=gnu99 -DHAVE_CONFIG_H -I.     -g -O2 -MT src/base32.o -MD -MP -MF $depbase.Tpo -c -o src/base32.o src/base32.c &&\
mv -f $depbase.Tpo $depbase.Po
depbase=`echo src/hmac.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
gcc -std=gnu99 -DHAVE_CONFIG_H -I.     -g -O2 -MT src/hmac.o -MD -MP -MF $depbase.Tpo -c -o src/hmac.o src/hmac.c &&\
mv -f $depbase.Tpo $depbase.Po
depbase=`echo src/sha1.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
gcc -std=gnu99 -DHAVE_CONFIG_H -I.     -g -O2 -MT src/sha1.o -MD -MP -MF $depbase.Tpo -c -o src/sha1.o src/sha1.c &&\
mv -f $depbase.Tpo $depbase.Po
/bin/sh ./libtool  --tag=CC   --mode=link gcc -std=gnu99  -g -O2   -o google-authenticator src/google-authenticator.o src/base32.o src/hmac.o src/sha1.o  -ldl 
libtool: link: gcc -std=gnu99 -g -O2 -o google-authenticator src/google-authenticator.o src/base32.o src/hmac.o src/sha1.o  -ldl
make[1]: 離開目錄“/root/google-authenticator/libpam”
make[1]: 進入目錄“/root/google-authenticator/libpam”
 /usr/bin/mkdir -p '/usr/local/bin'
  /bin/sh ./libtool   --mode=install /usr/bin/install -c google-authenticator '/usr/local/bin'
libtool: install: /usr/bin/install -c google-authenticator /usr/local/bin/google-authenticator
 /usr/bin/mkdir -p '/usr/local/share/doc/google-authenticator'
 /usr/bin/install -c -m 644 FILEFORMAT README.md '/usr/local/share/doc/google-authenticator'
 /usr/bin/mkdir -p '/usr/local/share/doc/google-authenticator'
 /usr/bin/install -c -m 644 totp.html '/usr/local/share/doc/google-authenticator'
 /usr/bin/mkdir -p '/usr/local/lib/security'
 /bin/sh ./libtool   --mode=install /usr/bin/install -c   pam_google_authenticator.la '/usr/local/lib/security'
libtool: install: /usr/bin/install -c .libs/pam_google_authenticator.so /usr/local/lib/security/pam_google_authenticator.so
libtool: install: /usr/bin/install -c .libs/pam_google_authenticator.lai /usr/local/lib/security/pam_google_authenticator.la
libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/sbin" ldconfig -n /usr/local/lib/security
----------------------------------------------------------------------
Libraries have been installed in:
   /usr/local/lib/security

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,-rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
make[1]: 離開目錄“/root/google-authenticator/libpam”
View Code

安裝完成后,現在我們去配置系統P  AM 模塊中修改sshd 支持谷歌的認證,這就要求所有用戶先使用谷歌驗證SSH認證。在sshd 文件的第一行,內容如下:

[root@test ~]# vim /etc/pam.d/sshd 
auth       required pam_google_authenticator.so no_increment_hotp

配置sshd服務,/etc/ssh/sshd_config,主要修改以下3個值:

[root@test ~]# vim /etc/ssh/sshd_config 
...
PasswordAuthentication yes
ChallengeResponseAuthentication yes
UsePAM yes

注意:這里插一條錯誤記錄,測試過程中出現的。

[root@test ~]# tail -40f /var/log/secure
....
May 21 13:43:01 test sshd[3344]: PAM unable to dlopen(/usr/lib64/security/pam_google_authenticator.so): /usr/lib64/security/pam_google_authenticator.so: cannot open shared object file: No such file or directory
May 21 13:43:01 test sshd[3344]: PAM adding faulty module: /usr/lib64/security/pam_google_authenticator.so
May 21 13:43:03 test sshd[3346]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"

修改方法:創建軟鏈接即可,必須創建,或者直接復制過去也可。

[root@test ~]# ln -s /usr/local/lib/security/pam_google_authenticator.so /usr/lib64/security/pam_google_authenticator.so 

 

之后,重啟sshd 服務

[root@test ~]# systemctl restart sshd

4.3.5 安裝二維碼生成工具。這步✌也可以省略,如果不裝的話,因為下一步生成的二維碼就會成一個鏈接,到時將鏈接復制到你的瀏覽器中,也是可以出現二維碼的,到時利用智能手機打開google author 進行掃描。

[root@test ~]# wget -c http://fukuchi.org/works/qrencode/qrencode-3.4.4.tar.gz
[root@test ~]# tar zxvf qrencode-3.4.4.tar.gz 
[root@test ~]# cd qrencode-3.4.4
[root@test qrencode-3.4.4]# yum install libpng libpng-devel
[root@test qrencode-3.4.4]# ./configure 
[root@test qrencode-3.4.4]# make && make install

4.3.6 設置一個用戶,如下操作:

運行google-authenticator 命令,它將會在當前登陸用戶的家目錄中生成一個新的密鑰()

[root@test qrencode-3.4.4]# cd ~
[root@test ~]# google-authenticator

Do you want authentication tokens to be time-based (y/n) y
https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/root@test%3Fsecret%3DSLZTXLFJ5KT5TWMP%26issuer%3Dtest
  
                                                                                                                                                                                                                       
Your new secret key is: SLZTXLFJ5KT5TWMP
Your verification code is 237785
Your emergency scratch codes are:
  50173529
  93655635
  54015704
  20609194
  92637519

Do you want me to update your "/root/.google_authenticator" file (y/n) y

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

By default, tokens are good for 30 seconds. In order to compensate for
possible time-skew between the client and the server, we allow an extra
token before and after the current time. If you experience problems with
poor time synchronization, you can increase the window from its default
size of +-1min (window size of 3) to about +-4min (window size of
17 acceptable tokens).
Do you want to do so? (y/n) y

If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting (y/n) y

上述共需回答5個y
  第1個:問你是否想做一個基於時間的令牌
  第2個:是否更新你的google認證文件,由於第一次設置,所以一定選y 
  第3個:是否禁止口令多用,這里選擇y,禁止它,以防止中間人欺騙。
  第4個:默認情況,1個口令的有效期是30s,這里是為了防止主機時間和口令客戶端時間不一致,設置的誤差,可以選擇y,也可選n,看要求嚴謹程度
  第5個:是否打開嘗試次數限制,默認情況,30s內不得超過3次登陸測試,防止別人暴力破解

並且上面這些設置將被存儲在用戶的〜/.google_authenticator文件中,emergency scratch codes 中的5個代碼是緊急代碼,務必牢記,這是在你的動態口令無法使用的情況下使用的,記住,用一個失效一個。后期可以登陸上去后,重新生成!!

上面的二維碼如果你沒有做 4.3.5 安裝qrencode那一步,可以復制鏈接,直接粘貼到瀏覽器地址欄中,進行生成,此時打開手機上的Google Authenticator應用掃描二維碼,操作如下圖:

-->> 

 

從上面的圖中可以看出,認證圖片已經掃描成功。並且動態口令的左下方有該機器的主機名。

五、測試

5.1 注銷當前用戶后,重新登陸

六、優化

6.1 不足之處

  上面的環境即使在內網還是需要二次認證;所以這個好解決,將允許本地局域網直接登錄系統。

6.2 解決內網主機跳過二次認證

編輯pam.d下的sshd 文件,在第一行增加內容,主要是指定允許的主機信息文件,如下所示:

[root@test ~]# more -2 /etc/pam.d/sshd 
auth [success=1 default=ignore] pam_access.so accessfile=/etc/security/access-localhost.conf
auth       required pam_google_authenticator.so no_increment_hotp

然后在/etc/security/目錄下創建access-localhost.conf文件,並添加內容如下:

[root@test ~]# cat /etc/security/access-localhost.conf
# skipped local network for google auth...
+ : ALL : 192.168.1.0/24
+ : ALL : LOCAL
- : ALL : ALL

最后,重啟sshd 服務

[root@test ~]# systemctl restart sshd

6.3 測試,內網主機登陸便直接使用密鑰登陸了。

lk:~ yifeng$ ssh root@192.168.1.125
Password: 
Last login: Sun May 22 02:21:46 2016 from 192.168.1.101

6.4 結論

  從上面的部署來看,部署不是特別的難,可以說很簡單吧,應用場景也可以有很多,可以用在公司內部堡壘機上,以及個人的網站、博客虛擬主機上。從而給系統加了一層保障,增強了個人服務器的安全性。

 

 

 

本文章屬於原創,如有轉載還望注明出處。謝謝

 

2016-12-10日 更正記錄:由於谷歌 github上將libpam 認證模塊放到一個單獨項目內,4.3.4步驟已過時,文中已給出最新下載源碼方式。

 

參考文章:

https://github.com/google/google-authenticator

http://www.zhihu.com/question/20462696

https://github.com/google/google-authenticator-libpam 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM