一、介绍:什么是双因素认证

  双因素身份认证就是通过你所知道再加上你所能拥有的这二个要素组合到一起才能发挥作用的身份认证系统。双因素认证是一种采用时间同步技术的系统,采用了基于时间、事件和密钥三变量而产生的一次性密码来代替传统的静态密码。每个动态密码卡都有一个唯一的密钥,该密钥同时存放在服务器端,每次认证时动态密码卡与服务器分别根据同样的密钥,同样的随机参数(时间、事件)和同样的算法计算了认证的动态密码,从而确保密码的一致性,从而实现了用户的认证。

  说白了,就像我们几年前去银行办卡送的口令牌,以及网易游戏中的将军令,在你使用网银或登陆游戏时会再让你输入动态口令的。

二、产品分类

  市面上有基于硬件的,也有基于软件的产品,具体可以另搜啊,本人喜欢开源的东东,并找到了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 .cn.pool.ntp.org iburst

重启服务并使用命令查看同步(注:202.118.1.130就是我们上一步添加的那个ntp server)

[root@test ~]# systemctl restart chronyd
[root@test ~]# chronyc sources
Number of sources =
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 202.118.1.130 -58us[ +132us] +/- 85ms
^+ news.neu.edu.cn +542us[ +732us] +/- 89ms
^- dns1.synet.edu.cn +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: , done.
remote: Total (delta ), reused (delta ), pack-reused
接收对象中: % (/), 2.33 MiB | 86.00 KiB/s, done.
处理 delta 中: % (/), 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:: installing 'build/config.guess'
configure.ac:: installing 'build/config.sub'
configure.ac:: installing 'build/install-sh'
configure.ac:: 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...
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[]: 进入目录“/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 >&
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 >&
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 >&
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 >&
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[]: 离开目录“/root/google-authenticator/libpam”
make[]: 进入目录“/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 FILEFORMAT README.md '/usr/local/share/doc/google-authenticator'
/usr/bin/mkdir -p '/usr/local/share/doc/google-authenticator'
/usr/bin/install -c -m 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() and ld.so() manual pages.
----------------------------------------------------------------------
make[]: 离开目录“/root/google-authenticator/libpam”

安装完成后,现在我们去配置系统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 :: test sshd[]: 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 :: test sshd[]: PAM adding faulty module: /usr/lib64/security/pam_google_authenticator.so
May :: test sshd[]: 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..tar.gz
[root@test ~]# cd qrencode-3.4.
[root@test qrencode-3.4.]# yum install libpng libpng-devel
[root@test qrencode-3.4.]# ./configure
[root@test qrencode-3.4.]# make && make install

4.3.6 设置一个用户,如下操作:

运行google-authenticator 命令,它将会在当前登陆用户的家目录中生成一个新的密钥()

[root@test qrencode-3.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
Your emergency scratch codes are: 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 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 ) to about +-4min (window size of
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 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 - /etc/pam.d/sshd
auth [success= 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/
+ : 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 :: 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

Linux 之 利用Google Authenticator实现用户双因素认证的更多相关文章

  1. Linux 利用Google Authenticator实现ssh登录双因素认证

    1.介绍 双因素认证:双因素身份认证就是通过你所知道再加上你所能拥有的这二个要素组合到一起才能发挥作用的身份认证系统.双因素认证是一种采用时间同步技术的系统,采用了基于时间.事件和密钥三变量而产生的一 ...

  2. 业余草双因素认证(2FA)教程

    所谓认证(authentication)就是确认用户的身份,是网站登录必不可少的步骤.密码是最常见的认证方法,但是不安全,容易泄露和冒充.越来越多的地方,要求启用双因素认证(Two-factor au ...

  3. 双因素认证(2FA)教程

    所谓认证(authentication)就是确认用户的身份,是网站登录必不可少的步骤. 密码是最常见的认证方法,但是不安全,容易泄露和冒充. 越来越多的地方,要求启用 双因素认证(Two-factor ...

  4. 轻松搭建CAS 5.x系列(8)-在CAS Server增加双因素认证(DUO版)

    概述说明 为了让系统更加安全,很多登录会加入双因素认证.何为双因素,如果把登陆作为开一扇门的话,那就是在原来的锁上再加一把锁,第二锁用新的钥匙,这样安全系数就更加高了. CAS是通过账号名和密码来认证 ...

  5. 【Linux】使用Google Authenticator 实现ssh登录双因素认证

    一般来说,使用ssh远程登录服务器,只需要输入账号和密码,显然这种方式不是很安全.为了安全着想,可以使用GoogleAuthenticator(谷歌身份验证器),以便在账号和密码之间再增加一个验证码, ...

  6. Linux下部署SSH登录时的二次身份验证环境记录(利用Google Authenticator)

    一般来说,使用ssh远程登录服务器,只需要输入账号和密码,显然这种方式不是很安全.为了安全着想,可以使用GoogleAuthenticator(谷歌身份验证器),以便在账号和密码之间再增加一个验证码, ...

  7. Linux下使用Google Authenticator配置SSH登录动态验证码

    1.一般ssh登录服务器,只需要输入账号和密码.2.本教程的目的:在账号和密码之间再增加一个验证码,只有输入正确的验证码之后,再输入密码才能登录.这样就增强了ssh登录的安全性.3.账号.验证码.密码 ...

  8. java 双因素认证(2FA)TOTP demo

    TOTP 的全称是"基于时间的一次性密码"(Time-based One-time Password).它是公认的可靠解决方案,已经写入国际标准 RFC6238. 很早就知道有这个 ...

  9. Google Authenticator

    Google Authenticator 现在越来越多的网站采用两步验证,实现方式可能有所区别,一般来说是 1+? (1 即 普通的用户名和密码, ?可能是实物如U盾.手机短信验证码或其他).?的重点 ...

随机推荐

  1. three.js入门系列之视角和辅助线

    假设你已经创建好了three.js的开发环境(我是写在vue项目中的),那么接下来,从头开始演示是如何用three.js来构建3D图形的.(笔记本写的代码,屏幕小,所以为了能够整屏看到完整代码,就将字 ...

  2. rabbitMQ高可用

    镜像模式 镜像模式和普通模式的区别就是,队列的数据都镜像了一份到所有的节点上.这样任何一个节点失效,不会影响整个集群的使用. 在实现上,mirror queue内部有一套选举算法,会选出一个maste ...

  3. JAXP使用Stax API时格式化输出XML 2

    之前实现的一个版本:http://www.cnblogs.com/lyhtbc/p/jaxp-pretty-format-validate-validation-stax-stax2.html 这个版 ...

  4. Spring配置--Aop配置详情

    首先我们来看一下官方文档所给我们的关于AOP的一些概念性词语的解释: 切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象.事务管理是J2EE应用中一个关于横切关注点的很好的例子.在 ...

  5. cordova学习-基础篇

    Cordova 学习笔记(一):快速开始 1.安装cordova Cordova安装可以通过node.js从npm上获取.npm install -g cordova 通过这个命令可以安装cordov ...

  6. 错误:'class QApplication' has no member named 'setMainwidget'

    错误:'class QApplication' has no member named 'setMainwidget' 转自:http://blog.csdn.net/chenqiai0/articl ...

  7. jquery 给新增的addClass 使用css样式

    假如有一个情况,当导航url找不到相同的地址,就会出现找不到地址,高亮当前导航不出现 解决 办法 记得使用文档载入完成后执行的函数. 因为 .current 是 addClass 新增的class $ ...

  8. 【mongodb】Mongodb初识

    MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系 ...

  9. 【DUBBO】Dubbo原理解析-服务发布

    转载:http://blog.csdn.net/quhongwei_zhanqiu/article/details/41651205 服务发布方在spring的配置文件中配置如下: <bean ...

  10. grpc rust 项目基本使用

    1. 安装依赖(rust 基本依赖就不说了,需要配置环境变量) protoc 参考: https://github.com/google/protobuf/releases/tag/v3.5.1 2. ...