分类 技术 下的文章

二进制分析是计算机行业中最被低估的技能。

想象一下,在无法访问软件的源代码时,但仍然能够理解软件的实现方式,在其中找到漏洞,并且更厉害的是还能修复错误。所有这些都是在只有二进制文件时做到的。这听起来就像是超能力,对吧?

你也可以拥有这样的超能力,GNU 二进制实用程序(binutils)就是一个很好的起点。GNU binutils 是一个二进制工具集,默认情况下所有 Linux 发行版中都会安装这些二进制工具。

二进制分析是计算机行业中最被低估的技能。它主要由恶意软件分析师、反向工程师和使用底层软件的人使用。

本文探讨了 binutils 可用的一些工具。我使用的是 RHEL,但是这些示例应该在任何 Linux 发行版上可以运行。

[~]# cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 7.6 (Maipo)
[~]# 
[~]# uname -r
3.10.0-957.el7.x86_64
[~]# 

请注意,某些打包命令(例如 rpm)在基于 Debian 的发行版中可能不可用,因此请使用等效的 dpkg 命令替代。

软件开发的基础知识

在开源世界中,我们很多人都专注于源代码形式的软件。当软件的源代码随时可用时,很容易获得源代码的副本,打开喜欢的编辑器,喝杯咖啡,然后就可以开始探索了。

但是源代码不是在 CPU 上执行的代码,在 CPU 上执行的是二进制或者说是机器语言指令。二进制或可执行文件是编译源代码时获得的。熟练的调试人员深谙通常这种差异。

编译的基础知识

在深入研究 binutils 软件包本身之前,最好先了解编译的基础知识。

编译是将程序从某种编程语言(如 C/C++)的源代码(文本形式)转换为机器代码的过程。

机器代码是 CPU(或一般而言,硬件)可以理解的 1 和 0 的序列,因此可以由 CPU 执行或运行。该机器码以特定格式保存到文件,通常称为可执行文件或二进制文件。在 Linux(和使用 Linux 兼容二进制的 BSD)上,这称为 ELF 可执行和可链接格式 Executable and Linkable Format )。

在生成给定的源文件的可执行文件或二进制文件之前,编译过程将经历一系列复杂的步骤。以这个源程序(C 代码)为例。打开你喜欢的编辑器,然后键入以下程序:

#include <stdio.h>

int main(void)
{
  printf("Hello World\n");
  return 0;
}

步骤 1:用 cpp 预处理

C 预处理程序(cpp)用于扩展所有宏并将头文件包含进来。在此示例中,头文件 stdio.h 将被包含在源代码中。stdio.h 是一个头文件,其中包含有关程序内使用的 printf 函数的信息。对源代码运行 cpp,其结果指令保存在名为 hello.i 的文件中。可以使用文本编辑器打开该文件以查看其内容。打印 “hello world” 的源代码在该文件的底部。

[testdir]# cat hello.c
#include <stdio.h>

int main(void)
{
  printf("Hello World\n");
  return 0;
}
[testdir]#
[testdir]# cpp hello.c > hello.i
[testdir]#
[testdir]# ls -lrt
total 24
-rw-r--r--. 1 root root 76 Sep 13 03:20 hello.c
-rw-r--r--. 1 root root 16877 Sep 13 03:22 hello.i
[testdir]#

步骤 2:用 gcc 编译

在此阶段,无需创建目标文件就将步骤 1 中生成的预处理源代码转换为汇编语言指令。这个阶段使用 GNU 编译器集合(gcc)。对 hello.i 文件运行带有 -S 选项的 gcc 命令后,它将创建一个名为 hello.s 的新文件。该文件包含该 C 程序的汇编语言指令。

你可以使用任何编辑器或 cat 命令查看其内容。

[testdir]#
[testdir]# gcc -Wall -S hello.i
[testdir]#
[testdir]# ls -l
total 28
-rw-r--r--. 1 root root 76 Sep 13 03:20 hello.c
-rw-r--r--. 1 root root 16877 Sep 13 03:22 hello.i
-rw-r--r--. 1 root root 448 Sep 13 03:25 hello.s
[testdir]#
[testdir]# cat hello.s
.file "hello.c"
.section .rodata
.LC0:
.string "Hello World"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $.LC0, %edi
call puts
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36)"
.section .note.GNU-stack,"",@progbits
[testdir]#

步骤 3:用 as 汇编

汇编器的目的是将汇编语言指令转换为机器语言代码,并生成扩展名为 .o 的目标文件。此阶段使用默认情况下在所有 Linux 平台上都可用的 GNU 汇编器。

testdir]# as hello.s -o hello.o
[testdir]#
[testdir]# ls -l
total 32
-rw-r--r--. 1 root root 76 Sep 13 03:20 hello.c
-rw-r--r--. 1 root root 16877 Sep 13 03:22 hello.i
-rw-r--r--. 1 root root 1496 Sep 13 03:39 hello.o
-rw-r--r--. 1 root root 448 Sep 13 03:25 hello.s
[testdir]#

现在,你有了第一个 ELF 格式的文件;但是,还不能执行它。稍后,你将看到“ 目标文件 object file ”和“ 可执行文件 executable file ”之间的区别。

[testdir]# file hello.o
hello.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

步骤 4:用 ld 链接

这是编译的最后阶段,将目标文件链接以创建可执行文件。可执行文件通常需要外部函数,这些外部函数通常来自系统库(libc)。

你可以使用 ld 命令直接调用链接器;但是,此命令有些复杂。相反,你可以使用带有 -v(详细)标志的 gcc 编译器,以了解链接是如何发生的。(使用 ld 命令进行链接作为一个练习,你可以自行探索。)

[testdir]# gcc -v hello.o
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man [...] --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:[...]:/usr/lib/gcc/x86_64-redhat-linux/
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-mtune=generic' '-march=x86-64'
/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu [...]/../../../../lib64/crtn.o
[testdir]#

运行此命令后,你应该看到一个名为 a.out 的可执行文件:

[testdir]# ls -l
total 44
-rwxr-xr-x. 1 root root 8440 Sep 13 03:45 a.out
-rw-r--r--. 1 root root 76 Sep 13 03:20 hello.c
-rw-r--r--. 1 root root 16877 Sep 13 03:22 hello.i
-rw-r--r--. 1 root root 1496 Sep 13 03:39 hello.o
-rw-r--r--. 1 root root 448 Sep 13 03:25 hello.s

a.out 运行 file 命令,结果表明它确实是 ELF 可执行文件:

[testdir]# file a.out
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=48e4c11901d54d4bf1b6e3826baf18215e4255e5, not stripped

运行该可执行文件,看看它是否如源代码所示工作:

[testdir]# ./a.out Hello World

工作了!在幕后发生了很多事情它才在屏幕上打印了 “Hello World”。想象一下在更复杂的程序中会发生什么。

探索 binutils 工具

上面这个练习为使用 binutils 软件包中的工具提供了良好的背景。我的系统带有 binutils 版本 2.27-34;你的 Linux 发行版上的版本可能有所不同。

[~]# rpm -qa | grep binutils 
binutils-2.27-34.base.el7.x86_64

binutils 软件包中提供了以下工具:

[~]# rpm -ql binutils-2.27-34.base.el7.x86_64 | grep bin/
/usr/bin/addr2line
/usr/bin/ar
/usr/bin/as
/usr/bin/c++filt
/usr/bin/dwp
/usr/bin/elfedit
/usr/bin/gprof
/usr/bin/ld
/usr/bin/ld.bfd
/usr/bin/ld.gold
/usr/bin/nm
/usr/bin/objcopy
/usr/bin/objdump
/usr/bin/ranlib
/usr/bin/readelf
/usr/bin/size
/usr/bin/strings
/usr/bin/strip

上面的编译练习已经探索了其中的两个工具:用作汇编器的 as 命令,用作链接器的 ld 命令。继续阅读以了解上述 GNU binutils 软件包工具中的其他七个。

readelf:显示 ELF 文件信息

上面的练习提到了术语“目标文件”和“可执行文件”。使用该练习中的文件,通过带有 -h(标题)选项的 readelf 命令,以将文件的 ELF 标题转储到屏幕上。请注意,以 .o 扩展名结尾的目标文件显示为 Type: REL (Relocatable file)(可重定位文件):

[testdir]# readelf -h hello.o
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 [...]
[...]
Type: REL (Relocatable file)
[...]

如果尝试执行此目标文件,会收到一条错误消息,指出无法执行。这仅表示它尚不具备在 CPU 上执行所需的信息。

请记住,你首先需要使用 chmod 命令在对象文件上添加 x(可执行位),否则你将得到“权限被拒绝”的错误。

[testdir]# ./hello.o
bash: ./hello.o: Permission denied
[testdir]# chmod +x ./hello.o
[testdir]#
[testdir]# ./hello.o
bash: ./hello.o: cannot execute binary file

如果对 a.out 文件尝试相同的命令,则会看到其类型为 EXEC (Executable file)(可执行文件)。

[testdir]# readelf -h a.out
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
[...] Type: EXEC (Executable file)

如上所示,该文件可以直接由 CPU 执行:

[testdir]# ./a.out Hello World

readelf 命令可提供有关二进制文件的大量信息。在这里,它会告诉你它是 ELF 64 位格式,这意味着它只能在 64 位 CPU 上执行,而不能在 32 位 CPU 上运行。它还告诉你它应在 X86-64(Intel/AMD)架构上执行。该二进制文件的入口点是地址 0x400430,它就是 C 源程序中 main 函数的地址。

在你知道的其他系统二进制文件上尝试一下 readelf 命令,例如 ls。请注意,在 RHEL 8 或 Fedora 30 及更高版本的系统上,由于安全原因改用了 位置无关可执行文件 position independent executable PIE),因此你的输出(尤其是 Type:)可能会有所不同。

[testdir]# readelf -h /bin/ls
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)

使用 ldd 命令了解 ls 命令所依赖的系统库,如下所示:

[testdir]# ldd /bin/ls
linux-vdso.so.1 => (0x00007ffd7d746000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f060daca000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007f060d8c5000)
libacl.so.1 => /lib64/libacl.so.1 (0x00007f060d6bc000)
libc.so.6 => /lib64/libc.so.6 (0x00007f060d2ef000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f060d08d000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f060ce89000)
/lib64/ld-linux-x86-64.so.2 (0x00007f060dcf1000)
libattr.so.1 => /lib64/libattr.so.1 (0x00007f060cc84000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f060ca68000)

libc 库文件运行 readelf 以查看它是哪种文件。正如它指出的那样,它是一个 DYN (Shared object file)(共享对象文件),这意味着它不能直接执行;必须由内部使用了该库提供的任何函数的可执行文件使用它。

[testdir]# readelf -h /lib64/libc.so.6
ELF Header:
Magic: 7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - GNU
ABI Version: 0
Type: DYN (Shared object file)

size:列出节的大小和全部大小

size 命令仅适用于目标文件和可执行文件,因此,如果尝试在简单的 ASCII 文件上运行它,则会抛出错误,提示“文件格式无法识别”。

[testdir]# echo "test" > file1
[testdir]# cat file1
test
[testdir]# file file1
file1: ASCII text
[testdir]# size file1
size: file1: File format not recognized

现在,在上面的练习中,对目标文件和可执行文件运行 size 命令。请注意,根据 size 命令的输出可以看出,可执行文件(a.out)的信息要比目标文件(hello.o)多得多:

[testdir]# size hello.o
text data bss dec hex filename
89 0 0 89 59 hello.o
[testdir]# size a.out
text data bss dec hex filename
1194 540 4 1738 6ca a.out

但是这里的 textdatabss 节是什么意思?

text 节是指二进制文件的代码部分,其中包含所有可执行指令。data 节是所有初始化数据所在的位置,bss 节是所有未初始化数据的存储位置。(LCTT 译注:一般来说,在静态的映像文件中,各个部分称之为 section ,而在运行时的各个部分称之为 segment ,有时统称为段。)

比较其他一些可用的系统二进制文件的 size 结果。

对于 ls 命令:

[testdir]# size /bin/ls
text data bss dec hex filename
103119 4768 3360 111247 1b28f /bin/ls

只需查看 size 命令的输出,你就可以看到 gccgdb 是比 ls 大得多的程序:

[testdir]# size /bin/gcc
text data bss dec hex filename
755549 8464 81856 845869 ce82d /bin/gcc
[testdir]# size /bin/gdb
text data bss dec hex filename
6650433 90842 152280 6893555 692ff3 /bin/gdb

strings:打印文件中的可打印字符串

strings 命令中添加 -d 标志以仅显示 data 节中的可打印字符通常很有用。

hello.o 是一个目标文件,其中包含打印出 Hello World 文本的指令。因此,strings 命令的唯一输出是 Hello World

[testdir]# strings -d hello.o 
Hello World

另一方面,在 a.out(可执行文件)上运行 strings 会显示在链接阶段该二进制文件中包含的其他信息:

[testdir]# strings -d a.out
/lib64/ld-linux-x86-64.so.2
!^BU
libc.so.6
puts
__libc_start_main
__gmon_start__
GLIBC_2.2.5
UH-0
UH-0
=(
[]A\A]A^A_
Hello World
;*3$"

objdump:显示目标文件信息

另一个可以从二进制文件中转储机器语言指令的 binutils 工具称为 objdump。使用 -d 选项,可从二进制文件中反汇编出所有汇编指令。

回想一下,编译是将源代码指令转换为机器代码的过程。机器代码仅由 1 和 0 组成,人类难以阅读。因此,它有助于将机器代码表示为汇编语言指令。汇编语言是什么样的?请记住,汇编语言是特定于体系结构的;由于我使用的是 Intel(x86-64)架构,因此如果你使用 ARM 架构编译相同的程序,指令将有所不同。

[testdir]# objdump -d hello.o
hello.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000
:
0:  55              push %rbp
1:  48 89 e5        mov %rsp,%rbp
4:  bf 00 00 00 00  mov $0x0,%edi
9:  e8 00 00 00 00  callq e

e:  b8 00 00 00 00  mov $0x0,%eax
13: 5d              pop %rbp
14: c3              retq

该输出乍一看似乎令人生畏,但请花一点时间来理解它,然后再继续。回想一下,.text 节包含所有的机器代码指令。汇编指令可以在第四列中看到(即 pushmovcallqpopretq 等)。这些指令作用于寄存器,寄存器是 CPU 内置的存储器位置。本示例中的寄存器是 rbprspedieax 等,并且每个寄存器都有特殊的含义。

现在对可执行文件(a.out)运行 objdump 并查看得到的内容。可执行文件的 objdump 的输出可能很大,因此我使用 grep 命令将其缩小到 main 函数:

[testdir]# objdump -d a.out | grep -A 9 main\>
000000000040051d
:
40051d: 55              push %rbp
40051e: 48 89 e5        mov %rsp,%rbp
400521: bf d0 05 40 00  mov $0x4005d0,%edi
400526: e8 d5 fe ff ff  callq 400400
40052b: b8 00 00 00 00  mov $0x0,%eax
400530: 5d              pop %rbp
400531: c3              retq

请注意,这些指令与目标文件 hello.o 相似,但是其中包含一些其他信息:

  • 目标文件 hello.o 具有以下指令:callq e
  • 可执行文件 a.out 由以下指令组成,该指令带有一个地址和函数:callq 400400 <puts@plt> 上面的汇编指令正在调用 puts 函数。请记住,你在源代码中使用了一个 printf 函数。编译器插入了对 puts 库函数的调用,以将 Hello World 输出到屏幕。

查看 put 上方一行的说明:

  • 目标文件 hello.o 有个指令 movmov $0x0,%edi
  • 可执行文件 a.outmov 指令带有实际地址($0x4005d0)而不是 $0x0mov $0x4005d0,%edi

该指令将二进制文件中地址 $0x4005d0 处存在的内容移动到名为 edi 的寄存器中。

这个存储位置的内容中还能是别的什么吗?是的,你猜对了:它就是文本 Hello, World。你是如何确定的?

readelf 命令使你可以将二进制文件(a.out)的任何节转储到屏幕上。以下要求它将 .rodata(这是只读数据)转储到屏幕上:

[testdir]# readelf -x .rodata a.out

Hex dump of section '.rodata':
0x004005c0 01000200 00000000 00000000 00000000 ....
0x004005d0 48656c6c 6f20576f 726c6400 Hello World.

你可以在右侧看到文本 Hello World,在左侧可以看到其二进制格式的地址。它是否与你在上面的 mov 指令中看到的地址匹配?是的,确实匹配。

strip:从目标文件中剥离符号

该命令通常用于在将二进制文件交付给客户之前减小二进制文件的大小。

请记住,由于重要信息已从二进制文件中删除,因此它会妨碍调试。但是,这个二进制文件可以完美地执行。

a.out 可执行文件运行该命令,并注意会发生什么。首先,通过运行以下命令确保二进制文件没有被剥离(not stripped):

[testdir]# file a.out
a.out: ELF 64-bit LSB executable, x86-64, [......] not stripped

另外,在运行 strip 命令之前,请记下二进制文件中最初的字节数:

[testdir]# du -b a.out
8440 a.out

现在对该可执行文件运行 strip 命令,并使用 file 命令以确保正常完成:

[testdir]# strip a.out
[testdir]# file a.out a.out: ELF 64-bit LSB executable, x86-64, [......] stripped

剥离该二进制文件后,此小程序的大小从之前的 8440 字节减小为 6296 字节。对于这样小的一个程序都能有这么大的空间节省,难怪大型程序经常被剥离。

[testdir]# du -b a.out 
6296 a.out

addr2line:转换地址到文件名和行号

addr2line 工具只是在二进制文件中查找地址,并将其与 C 源代码程序中的行进行匹配。很酷,不是吗?

为此编写另一个测试程序;只是这一次确保使用 gcc-g 标志进行编译,这将为二进制文件添加其它调试信息,并包含有助于调试的行号(由源代码中提供):

[testdir]# cat -n atest.c
1  #include <stdio.h>
2
3  int globalvar = 100;
4
5  int function1(void)
6  {
7    printf("Within function1\n");
8    return 0;
9  }
10
11 int function2(void)
12 {
13   printf("Within function2\n");
14   return 0;
15 }
16
17 int main(void)
18 {
19   function1();
20   function2();
21   printf("Within main\n");
22   return 0;
23 }

-g 标志编译并执行它。正如预期:

[testdir]# gcc -g atest.c
[testdir]# ./a.out
Within function1
Within function2
Within main

现在使用 objdump 来标识函数开始的内存地址。你可以使用 grep 命令来过滤出所需的特定行。函数的地址在下面突出显示(55 push %rbp 前的地址):

[testdir]# objdump -d a.out | grep -A 2 -E 'main>:|function1>:|function2>:'
000000000040051d :
40051d: 55 push %rbp
40051e: 48 89 e5 mov %rsp,%rbp
--
0000000000400532 :
400532: 55 push %rbp
400533: 48 89 e5 mov %rsp,%rbp
--
0000000000400547
:
400547: 55 push %rbp
400548: 48 89 e5 mov %rsp,%rbp

现在,使用 addr2line 工具从二进制文件中的这些地址映射到 C 源代码匹配的地址:

[testdir]# addr2line -e a.out 40051d
/tmp/testdir/atest.c:6
[testdir]#
[testdir]# addr2line -e a.out 400532
/tmp/testdir/atest.c:12
[testdir]#
[testdir]# addr2line -e a.out 400547
/tmp/testdir/atest.c:18

它说 40051d 从源文件 atest.c 中的第 6 行开始,这是 function1 的起始大括号({)开始的行。function2main 的输出也匹配。

nm:列出目标文件的符号

使用上面的 C 程序测试 nm 工具。使用 gcc 快速编译并执行它。

[testdir]# gcc atest.c
[testdir]# ./a.out
Within function1
Within function2
Within main

现在运行 nmgrep 获取有关函数和变量的信息:

[testdir]# nm a.out | grep -Ei 'function|main|globalvar'
000000000040051d T function1
0000000000400532 T function2
000000000060102c D globalvar
U __libc_start_main@@GLIBC_2.2.5
0000000000400547 T main

你可以看到函数被标记为 T,它表示 text 节中的符号,而变量标记为 D,表示初始化的 data 节中的符号。

想象一下在没有源代码的二进制文件上运行此命令有多大用处?这使你可以窥视内部并了解使用了哪些函数和变量。当然,除非二进制文件已被剥离,这种情况下它们将不包含任何符号,因此 nm 就命令不会很有用,如你在此处看到的:

[testdir]# strip a.out
[testdir]# nm a.out | grep -Ei 'function|main|globalvar'
nm: a.out: no symbols

结论

GNU binutils 工具为有兴趣分析二进制文件的人提供了许多选项,这只是它们可以为你做的事情的冰山一角。请阅读每种工具的手册页,以了解有关它们以及如何使用它们的更多信息。


via: https://opensource.com/article/19/10/gnu-binutils

作者:Gaurav Kamathe 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

我们有时可能需要在远程机器上运行一些命令。如果只是偶尔进行的操作,要实现这个目的,可以登录到远程系统上直接执行命令。但是每次都这么做的话,就有点烦人了。既然如此,有没有摆脱这种麻烦操作的更佳方案?

是的,你可以从你本地系统上执行这些操作,而不用登录到远程系统上。这有什么好处吗?毫无疑问。这会为你节省很多好时光。

这是怎么实现的?SSH 允许你无需登录到远程计算机就可以在它上面运行命令。

通用语法如下所示:

$ ssh [用户名]@[远程主机名或 IP] [命令或脚本]

1) 如何通过 SSH 在远程 Linux 系统上运行命令

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行 df 命令

$ ssh [email protected] df -h

 Filesystem               Size  Used Avail Use% Mounted on
 /dev/mapper/centos-root   27G  4.4G   23G  17% /
 devtmpfs                 903M     0  903M   0% /dev
 tmpfs                    920M     0  920M   0% /dev/shm
 tmpfs                    920M  9.3M  910M   2% /run
 tmpfs                    920M     0  920M   0% /sys/fs/cgroup
 /dev/sda1               1014M  179M  836M  18% /boot
 tmpfs                    184M  8.0K  184M   1% /run/user/42
 tmpfs                    184M     0  184M   0% /run/user/1000

2) 如何通过 SSH 在远程 Linux 系统上运行多条命令

下面的例子允许用户通过 ssh 在远程 Linux 机器上一次运行多条命令。

同时在远程 Linux 系统上运行 uptime 命令和 free 命令。

$ ssh [email protected] "uptime && free -m"

 23:05:10 up 10 min,  0 users,  load average: 0.00, 0.03, 0.03

              total       used       free     shared    buffers     cached
 Mem:          1878        432       1445          1        100        134
 -/+ buffers/cache:        197       1680
 Swap:         3071          0       3071

3) 如何通过 SSH 在远程 Linux 系统上运行带 sudo 权限的命令

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行带有 sudo 权限fdisk 命令。

普通用户不允许执行系统二进制(/usr/sbin/)目录下提供的命令。用户需要 root 权限来运行它。

所以你需要 root 权限,好在 Linux 系统上运行 fdisk 命令which 命令返回给定命令的完整可执行路径。

$ which fdisk
 /usr/sbin/fdisk
$ ssh -t [email protected] "sudo fdisk -l"
 [sudo] password for daygeek:

 Disk /dev/sda: 32.2 GB, 32212254720 bytes, 62914560 sectors
 Units = sectors of 1 * 512 = 512 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes
 Disk label type: dos
 Disk identifier: 0x000bf685

 Device Boot      Start         End      Blocks   Id  System
 /dev/sda1   *        2048     2099199     1048576   83  Linux
 /dev/sda2         2099200    62914559    30407680   8e  Linux LVM

 Disk /dev/sdb: 10.7 GB, 10737418240 bytes, 20971520 sectors
 Units = sectors of 1 * 512 = 512 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes

 Disk /dev/mapper/centos-root: 29.0 GB, 28982640640 bytes, 56606720 sectors
 Units = sectors of 1 * 512 = 512 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes

 Disk /dev/mapper/centos-swap: 2147 MB, 2147483648 bytes, 4194304 sectors
 Units = sectors of 1 * 512 = 512 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes

 Connection to centos7.2daygeek.com closed.

4) 如何通过 SSH 在远程 Linux 系统上运行带 sudo 权限的服务控制命令

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行带有 sudo 权限的服务控制命令。

$ ssh -t [email protected] "sudo systemctl restart httpd"

 [sudo] password for daygeek:
 Connection to centos7.2daygeek.com closed.

5) 如何通过非标准端口 SSH 在远程 Linux 系统上运行命令

下面的例子允许用户通过 ssh 在使用了非标准端口的远程 Linux 机器上运行 hostnamectl 命令

$ ssh -p 2200 [email protected] hostnamectl

    Static hostname: Ubuntu18.2daygeek.com
          Icon name: computer-vm
            Chassis: vm
         Machine ID: 27f6c2febda84dc881f28fd145077187
            Boot ID: bbeccdf932be41ddb5deae9e5f15183d
     Virtualization: oracle
   Operating System: Ubuntu 18.04.2 LTS
             Kernel: Linux 4.15.0-60-generic
       Architecture: x86-64

6) 如何将远程系统的输出保存到本地系统

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行 top 命令,并将输出保存到本地系统。

$ ssh [email protected] "top -bc | head -n 35" > /tmp/top-output.txt
cat /tmp/top-output.txt

 top - 01:13:11 up 18 min,  1 user,  load average: 0.01, 0.05, 0.10
 Tasks: 168 total,   1 running, 167 sleeping,   0 stopped,   0 zombie
 %Cpu(s):  0.0 us,  6.2 sy,  0.0 ni, 93.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
 KiB Mem :  1882300 total,  1176324 free,   342392 used,   363584 buff/cache
 KiB Swap:  2097148 total,  2097148 free,        0 used.  1348140 avail Mem
 PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
  4943 daygeek   20   0  162052   2248   1612 R 10.0  0.1   0:00.07 top -bc
     1 root      20   0  128276   6936   4204 S  0.0  0.4   0:03.08 /usr/lib/sy+
     2 root      20   0       0      0      0 S  0.0  0.0   0:00.00 [kthreadd]
     3 root      20   0       0      0      0 S  0.0  0.0   0:00.25 [ksoftirqd/+
     4 root      20   0       0      0      0 S  0.0  0.0   0:00.00 [kworker/0:+
     5 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [kworker/0:+
     7 root      rt   0       0      0      0 S  0.0  0.0   0:00.00 [migration/+
     8 root      20   0       0      0      0 S  0.0  0.0   0:00.00 [rcu_bh]
     9 root      20   0       0      0      0 S  0.0  0.0   0:00.77 [rcu_sched]
    10 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [lru-add-dr+
    11 root      rt   0       0      0      0 S  0.0  0.0   0:00.01 [watchdog/0]
    13 root      20   0       0      0      0 S  0.0  0.0   0:00.00 [kdevtmpfs]
    14 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [netns]
    15 root      20   0       0      0      0 S  0.0  0.0   0:00.00 [khungtaskd]
    16 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [writeback]
    17 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [kintegrity+
    18 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [bioset]
    19 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [bioset]
    20 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [bioset]

或者你也可以使用以下格式在远程系统上运行多条命令:

$ ssh [email protected] << EOF
hostnamectl
free -m
grep daygeek /etc/passwd
EOF

上面命令的输出如下:

Pseudo-terminal will not be allocated because stdin is not a terminal.
    Static hostname: CentOS7.2daygeek.com
          Icon name: computer-vm
            Chassis: vm
         Machine ID: 002f47b82af248f5be1d67b67e03514c
            Boot ID: dca9a1ba06374d7d96678f9461752482
     Virtualization: kvm
   Operating System: CentOS Linux 7 (Core)
        CPE OS Name: cpe:/o:centos:centos:7
             Kernel: Linux 3.10.0-957.el7.x86_64
       Architecture: x86-64

               total        used        free      shared  buff/cache   available
 Mem:           1838         335        1146          11         355        1314
 Swap:          2047           0        2047

 daygeek:x:1000:1000:2daygeek:/home/daygeek:/bin/bash

7) 如何在远程系统上运行本地 Bash 脚本

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行本地 bash 脚本 remote-test.sh

创建一个 shell 脚本并执行它。

$ vi /tmp/remote-test.sh

#!/bin/bash
#Name: remote-test.sh
#--------------------
 uptime
 free -m
 df -h
 uname -a
 hostnamectl

上面命令的输出如下:

$ ssh [email protected] 'bash -s' < /tmp/remote-test.sh

  01:17:09 up 22 min,  1 user,  load average: 0.00, 0.02, 0.08

               total        used        free      shared  buff/cache   available
 Mem:           1838         333        1148          11         355        1316
 Swap:          2047           0        2047

 Filesystem               Size  Used Avail Use% Mounted on
 /dev/mapper/centos-root   27G  4.4G   23G  17% /
 devtmpfs                 903M     0  903M   0% /dev
 tmpfs                    920M     0  920M   0% /dev/shm
 tmpfs                    920M  9.3M  910M   2% /run
 tmpfs                    920M     0  920M   0% /sys/fs/cgroup
 /dev/sda1               1014M  179M  836M  18% /boot
 tmpfs                    184M   12K  184M   1% /run/user/42
 tmpfs                    184M     0  184M   0% /run/user/1000

 Linux CentOS7.2daygeek.com 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

    Static hostname: CentOS7.2daygeek.com
          Icon name: computer-vm
            Chassis: vm
         Machine ID: 002f47b82af248f5be1d67b67e03514c
            Boot ID: dca9a1ba06374d7d96678f9461752482
     Virtualization: kvm
   Operating System: CentOS Linux 7 (Core)
        CPE OS Name: cpe:/o:centos:centos:7
             Kernel: Linux 3.10.0-957.el7.x86_64
       Architecture: x86-64

或者也可以使用管道。如果你觉得输出不太好看,再做点修改让它更优雅些。

$ vi /tmp/remote-test-1.sh

#!/bin/bash
#Name: remote-test.sh
 echo "---------System Uptime--------------------------------------------"
 uptime
 echo -e "\n"
 echo "---------Memory Usage---------------------------------------------"
 free -m
 echo -e "\n"
 echo "---------Disk Usage-----------------------------------------------"
 df -h
 echo -e "\n"
 echo "---------Kernel Version-------------------------------------------"
 uname -a
 echo -e "\n"
 echo "---------HostName Info--------------------------------------------"
 hostnamectl
 echo "------------------------------------------------------------------"

上面脚本的输出如下:

$ cat /tmp/remote-test.sh  | ssh [email protected]
 Pseudo-terminal will not be allocated because stdin is not a terminal.
 ---------System Uptime--------------------------------------------
  03:14:09 up  2:19,  1 user,  load average: 0.00, 0.01, 0.05

 ---------Memory Usage---------------------------------------------
               total        used        free      shared  buff/cache   available
 Mem:           1838         376        1063          11         398        1253
 Swap:          2047           0        2047

 ---------Disk Usage-----------------------------------------------
 Filesystem               Size  Used Avail Use% Mounted on
 /dev/mapper/centos-root   27G  4.4G   23G  17% /
 devtmpfs                 903M     0  903M   0% /dev
 tmpfs                    920M     0  920M   0% /dev/shm
 tmpfs                    920M  9.3M  910M   2% /run
 tmpfs                    920M     0  920M   0% /sys/fs/cgroup
 /dev/sda1               1014M  179M  836M  18% /boot
 tmpfs                    184M   12K  184M   1% /run/user/42
 tmpfs                    184M     0  184M   0% /run/user/1000
 tmpfs                    184M     0  184M   0% /run/user/0

 ---------Kernel Version-------------------------------------------
 Linux CentOS7.2daygeek.com 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

 ---------HostName Info--------------------------------------------
    Static hostname: CentOS7.2daygeek.com
          Icon name: computer-vm
            Chassis: vm
         Machine ID: 002f47b82af248f5be1d67b67e03514c
            Boot ID: dca9a1ba06374d7d96678f9461752482
     Virtualization: kvm
   Operating System: CentOS Linux 7 (Core)
        CPE OS Name: cpe:/o:centos:centos:7
             Kernel: Linux 3.10.0-957.el7.x86_64
       Architecture: x86-64

8) 如何同时在多个远程系统上运行多条指令

下面的 bash 脚本允许用户同时在多个远程系统上运行多条指令。使用简单的 for 循环实现。

为了实现这个目的,你可以尝试 PSSH 命令ClusterShell 命令DSH 命令

$ vi /tmp/multiple-host.sh

 for host in CentOS7.2daygeek.com CentOS6.2daygeek.com
 do
    ssh daygeek@${host} "uname -a;uptime;date;w"
 done

上面脚本的输出如下:

$ sh multiple-host.sh

 Linux CentOS7.2daygeek.com 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

  01:33:57 up 39 min,  1 user,  load average: 0.07, 0.06, 0.06

 Wed Sep 25 01:33:57 CDT 2019

  01:33:57 up 39 min,  1 user,  load average: 0.07, 0.06, 0.06
 USER     TTY      FROM             [email protected]   IDLE   JCPU   PCPU WHAT
 daygeek  pts/0    192.168.1.6      01:08   23:25   0.06s  0.06s -bash

 Linux CentOS6.2daygeek.com 2.6.32-754.el6.x86_64 #1 SMP Tue Jun 19 21:26:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

  23:33:58 up 39 min,  0 users,  load average: 0.00, 0.00, 0.00

 Tue Sep 24 23:33:58 MST 2019

  23:33:58 up 39 min,  0 users,  load average: 0.00, 0.00, 0.00
 USER     TTY      FROM             [email protected]   IDLE   JCPU   PCPU WHAT

9) 如何使用 sshpass 命令添加一个密码

如果你觉得每次输入密码很麻烦,我建议你视你的需求选择以下方法中的一项来解决这个问题。

如果你经常进行类似的操作,我建议你设置 免密码认证,因为它是标准且永久的解决方案。

如果你一个月只是执行几次这些任务,我推荐你使用 sshpass 工具。只需要使用 -p 参数选项提供你的密码即可。

$ sshpass -p '在这里输入你的密码' ssh -p 2200 [email protected] ip a

 1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
     inet 127.0.0.1/8 scope host lo
        valid_lft forever preferred_lft forever
     inet6 ::1/128 scope host
        valid_lft forever preferred_lft forever
 2: eth0:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
     link/ether 08:00:27:18:90:7f brd ff:ff:ff:ff:ff:ff
     inet 192.168.1.12/24 brd 192.168.1.255 scope global dynamic eth0
        valid_lft 86145sec preferred_lft 86145sec
     inet6 fe80::a00:27ff:fe18:907f/64 scope link tentative dadfailed
        valid_lft forever preferred_lft forever

via: https://www.2daygeek.com/execute-run-linux-commands-remote-system-over-ssh/

作者:Magesh Maruthamuthu 选题:lujun9972 译者:alim0x 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

继 RHEL 8 发布之后,CentOS 社区也发布了让人期待已久的 CentOS 8,并发布了两种模式:

  • CentOS stream:滚动发布的 Linux 发行版,适用于需要频繁更新的开发者
  • CentOS:类似 RHEL 8 的稳定操作系统,系统管理员可以用其部署或配置服务和应用

在这篇文章中,我们会使用图解的方式演示 CentOS 8 的安装方法。

CentOS 8 的新特性

  • DNF 成为了默认的软件包管理器,同时 yum 仍然是可用的
  • 使用网络管理器(nmclinmtui)进行网络配置,移除了网络脚本
  • 使用 Podman 进行容器管理
  • 引入了两个新的包仓库:BaseOS 和 AppStream
  • 使用 Cockpit 作为默认的系统管理工具
  • 默认使用 Wayland 作为显示服务器
  • iptables 将被 nftables 取代
  • 使用 Linux 内核 4.18
  • 提供 PHP 7.2、Python 3.6、Ansible 2.8、VIM 8.0 和 Squid 4

CentOS 8 所需的最低硬件配置:

  • 2 GB RAM
  • 64 位 x86 架构、2 GHz 或以上的 CPU
  • 20 GB 硬盘空间

CentOS 8 安装图解

第一步:下载 CentOS 8 ISO 文件

在 CentOS 官方网站 https://www.centos.org/download/ 下载 CentOS 8 ISO 文件。

第二步: 创建 CentOS 8 启动介质(USB 或 DVD)

下载 CentOS 8 ISO 文件之后,将 ISO 文件烧录到 USB 移动硬盘或 DVD 光盘中,作为启动介质。

然后重启系统,在 BIOS 中设置为从上面烧录好的启动介质启动。

第三步:选择“安装 CentOS Linux 8.0”选项

当系统从 CentOS 8 ISO 启动介质启动之后,就可以看到以下这个界面。选择“Install CentOS Linux 8.0”(安装 CentOS Linux 8.0)选项并按回车。

Choose-Install-CentOS8

第四步:选择偏好语言

选择想要在 CentOS 8 安装过程中使用的语言,然后继续。

Select-Language-CentOS8-Installation

第五步:准备安装 CentOS 8

这一步我们会配置以下内容:

  • 键盘布局
  • 日期和时间
  • 安装来源
  • 软件选择
  • 安装目标
  • Kdump

Installation-Summary-CentOS8

如上图所示,安装向导已经自动提供了“ 键盘布局 Keyboard ”、“ 时间和日期 Time & Date ”、“ 安装来源 Installation Source ”和“ 软件选择 Software Selection ”的选项。

如果你需要修改以上设置,点击对应的图标就可以了。例如修改系统的时间和日期,只需要点击“ 时间和日期 Time & Date ”,选择正确的时区,然后点击“ 完成 Done ”即可。

TimeZone-CentOS8-Installation

在软件选择选项中选择安装的模式。例如“ 包含图形界面 Server with GUI ”选项会在安装后的系统中提供图形界面,而如果想安装尽可能少的额外软件,可以选择“ 最小化安装 Minimal Install ”。

Software-Selection-CentOS8-Installation

这里我们选择“ 包含图形界面 Server with GUI ”,点击“ 完成 Done ”。

Kdump 功能默认是开启的。尽管这是一个强烈建议开启的功能,但也可以点击对应的图标将其关闭。

如果想要在安装过程中对网络进行配置,可以点击“ 网络与主机名 Network & Host Name ”选项。

Networking-During-CentOS8-Installation

如果系统连接到启用了 DHCP 功能的调制解调器上,就会在启动网络接口的时候自动获取一个 IP 地址。如果需要配置静态 IP,点击“ 配置 Configure ”并指定 IP 的相关信息。除此以外我们还将主机名设置为 “linuxtechi.com”。

完成网络配置后,点击“ 完成 Done ”。

最后我们要配置“ 安装目标 Installation Destination ”,指定 CentOS 8 将要安装到哪一个硬盘,以及相关的分区方式。

Installation-Destination-Custom-CentOS8

点击“ 完成 Done ”。

如图所示,我为 CentOS 8 分配了 40 GB 的硬盘空间。有两种分区方案可供选择:如果由安装向导进行自动分区,可以从“ 存储配置 Storage Configuration ”中选择“ 自动 Automatic ”选项;如果想要自己手动进行分区,可以选择“ 自定义 Custom ”选项。

在这里我们选择“ 自定义 Custom ”选项,并按照以下的方式创建基于 LVM 的分区:

  • /boot – 2 GB (ext4 文件系统)
  • / – 12 GB (xfs 文件系统)
  • /home – 20 GB (xfs 文件系统)
  • /tmp – 5 GB (xfs 文件系统)
  • Swap – 1 GB (xfs 文件系统)

首先创建 /boot 标准分区,设置大小为 2GB,如下图所示:

boot-partition-CentOS8-Installation

点击“ 添加挂载点 Add mount point ”。

再创建第二个分区 /,并设置大小为 12GB。点击加号,指定挂载点和分区大小,点击“ 添加挂载点 Add mount point ”即可。

slash-root-partition-centos8-installation

然后在页面上将 / 分区的分区类型从标准更改为 LVM,并点击“ 更新设置 Update Settings ”。

Change-Partition-Type-CentOS8

如上图所示,安装向导已经自动创建了一个卷组。如果想要更改卷组的名称,只需要点击“ 卷组 Volume Group ”标签页中的“ 修改 Modify ”选项。

同样地,创建 /home 分区和 /tmp 分区,分别将大小设置为 20GB 和 5GB,并设置分区类型为 LVM。

home-partition-CentOS8-Installation

tmp-partition-centos8-installation

最后创建 交换分区 Swap Partition

Swap-Partition-CentOS8-Installation

点击“ 添加挂载点 Add mount point ”。

在完成所有分区设置后,点击“ 完成 Done ”。

Choose-Done-after-manual-partition-centos8

在下一个界面,点击“ 应用更改 Accept changes ”,以上做的更改就会写入到硬盘中。

Accept-changes-CentOS8-Installation

第六步:选择“开始安装”

完成上述的所有更改后,回到先前的安装概览界面,点击“ 开始安装 Begin Installation ”以开始安装 CentOS 8。

Begin-Installation-CentOS8

下面这个界面表示安装过程正在进行中。

Installation-progress-centos8

要设置 root 用户的口令,只需要点击 “ root 口令 Root Password ”选项,输入一个口令,然后点击“ 创建用户 User Creation ”选项创建一个本地用户。

Root-Password-CentOS8-Installation

填写新创建的用户的详细信息。

Local-User-Details-CentOS8

在安装完成后,安装向导会提示重启系统。

CentOS8-Installation-Progress

第七步:完成安装并重启系统

安装完成后要重启系统。只需点击“ 重启 Reboot ”按钮。

Installation-Completed-CentOS8

注意:重启完成后,记得要把安装介质断开,并将 BIOS 的启动介质设置为硬盘。

第八步:启动新安装的 CentOS 8 并接受许可协议

在 GRUB 引导菜单中,选择 CentOS 8 进行启动。

Grub-Boot-CentOS8

同意 CentOS 8 的许可证,点击“ 完成 Done ”。

Accept-License-CentOS8-Installation

在下一个界面,点击“ 完成配置 Finish Configuration ”。

Finish-Configuration-CentOS8-Installation

第九步:配置完成后登录

同意 CentOS 8 的许可证以及完成配置之后,会来到登录界面。

Login-screen-CentOS8

使用刚才创建的用户以及对应的口令登录,按照提示进行操作,就可以看到以下界面。

CentOS8-Ready-Use-Screen

点击“ 开始使用 CentOS Linux Start Using CentOS Linux ”。

Desktop-Screen-CentOS8

以上就是 CentOS 8 的安装过程,至此我们已经完成了 CentOS 8 的安装。

欢迎给我们发送评论。


via: https://www.linuxtechi.com/centos-8-installation-guide-screenshots/

作者:Pradeep Kumar 选题:lujun9972 译者:HankChow 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

使用这个基于 scrcpy 的开源应用从你的电脑上访问你的安卓设备。

在未来,你所需的一切信息皆触手可及,并且全部会以全息的形式出现在空中,即使你在驾驶汽车时也可以与之交互。不过,那是未来,在那一刻到来之前,我们所有人都只能将信息分散在笔记本电脑、手机、平板电脑和智能冰箱上。不幸的是,这意味着当我们需要来自该设备的信息时,我们通常必须查看该设备。

虽然不完全是像全息终端或飞行汽车那样酷炫,但 srevin saju 开发的 guiscrcpy 是一个可以在一个地方整合多个屏幕,让你有一点未来感觉的应用程序。

Guiscrcpy 是一个基于屡获殊荣的一个开源引擎 scrcpy 的一个开源项目(GUN GPLv3 许可证)。使用 Guiscrcpy 可以将你的安卓手机的屏幕投射到你的电脑,这样你就可以查看手机上的一切东西。Guiscrcpy 支持 Linux、Windows 和 MacOS。

不像其他 scrcpy 的替代软件一样,Guiscrcpy 并不仅仅是 scrcpy 的一个简单的复制品。该项目优先考虑了与其他开源项目的协作。因此,Guiscrcpy 对 scrcpy 来说是一个扩展,或者说是一个用户界面层。将 Python 3 GUI 与 scrcpy 分开可以确保没有任何东西干扰 scrcpy 后端的效率。你可以投射到 1080P 分辨率的屏幕,因为它的超快的渲染速度和超低的 CPU 使用,即使在低端的电脑上也可以运行的很顺畅。

Scrcpy 是 Guiscrcpy 项目的基石。它是一个基于命令行的应用,因此它没有处理你的手势操作的用户界面。它也没有提供返回按钮和主页按钮,而且它需要你对 Linux 终端比较熟悉。Guiscrcpy 给 scrcpy 添加了图形面板。因此,任何用户都可以使用它,而且不需要通过网络发送任何信息就可以投射和控制他的设备。Guiscrcpy 同时也为 Windows 用户和 Linux 用户提供了编译好的二进制文件,以方便你的使用。

安装 Guiscrcpy

在你安装 Guiscrcpy 之前,你需要先安装它的依赖包。尤其是要安装 scrcpy。安装 scrcpy 最简单的方式可能就是使用对于大部分 Linux 发行版都安装了的 snap 工具。如果你的电脑上安装并使用了 snap,那么你就可以使用下面的命令来一步安装 scrcpy。

$ sudo snap install scrcpy

当你安装完 scrcpy,你就可以安装其他的依赖包了。Simple DirectMedia Layer(SDL 2.0) 是一个显示和控制你设备屏幕的工具包。Android Debug Bridge (ADB) 命令可以连接你的安卓手机到电脑。

在 Fedora 或者 CentOS:

$ sudo dnf install SDL2 android-tools

在 Ubuntu 或者 Debian:

$ sudo apt install SDL2 android-tools-adb

在另一个终端中,安装 Python 依赖项:

$ python3 -m pip install -r requirements.txt --user

设置你的手机

为了能够让你的手机接受 adb 连接。必须让你的手机开启开发者选项。为了打开开发者选项,打开“设置”,然后选择“关于手机”,找到“版本号”(它也可能位于“软件信息”面板中)。不敢置信,只要你连续点击“版本号”七次,你就可以打开开发者选项。(LCTT 译注:显然这里是以 Google 原生的 Android 作为说明的,你的不同品牌的安卓手机打开开发者选项的方式或有不同。)

 title=

更多更全面的连接手机的方式,请参考安卓开发者文档

一旦你设置好了你的手机,将你的手机通过 USB 线插入到你的电脑中(或者通过无线的方式进行连接,确保你已经配置好了无线连接)。

使用 Guiscrcpy

当你启动 guiscrcpy 的时候,你就能看到一个主控制窗口。点击窗口里的 “Start scrcpy” 按钮。只要你设置好了开发者模式并且通过 USB 或者 WiFi 将你的手机连接到电脑。guiscrcpy 就会连接你的手机。

 title=

它还包括一个可写入的配置系统,你可以将你的配置文件写入到 ~/.config 目录。可以在使用前保存你的首选项。

guiscrcpy 底部的面板是一个浮动的窗口,可以帮助你执行一些基本的控制动作。它包括了主页按钮、返回按钮、电源按钮以及一些其他的按键。这些按键在安卓手机上都非常常用。值得注意的是,这个模块并不是与 scrcpy 的 SDL 进行交互。因此,它可以毫无延迟的执行。换句话说,这个操作窗口是直接通过 adb 与你的手机进行交互而不是通过 scrcpy。

 title=

这个项目目前十分活跃,不断地有新的特性加入其中。最新版本的具有了手势操作和通知界面。

有了这个 guiscrcpy,你不仅仅可以在你的电脑屏幕上看到你的手机,你还可以就像操作你的实体手机一样点击 SDL 窗口,或者使用浮动窗口上的按钮与之进行交互。

 title=

Guiscrcpy 是一个有趣且实用的应用程序,它提供的功能应该是任何现代设备(尤其是 Android 之类的平台)的正式功能。自己尝试一下,为当今的数字生活增添一些未来主义的感觉。


via: https://opensource.com/article/19/9/mirror-android-screen-guiscrcpy

作者:Seth Kenlon 选题:lujun9972 译者:amwps290 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

OneDrive 是微软的一项云存储服务,它为每个用户提供 5GB 的免费存储空间。它已与微软帐户集成,如果你使用 Windows,那么已在其中预安装了 OneDrive。

OneDrive 无法在 Linux 中作为桌面应用使用。你可以通过网页访问已存储的文件,但无法像在文件管理器中那样使用云存储。

好消息是,你现在可以使用一个非官方工具,它可让你在 Ubuntu 或其他 Linux 发行版中使用 OneDrive。

Insync 在 Linux 上支持 Google Drive 时,它变成了 Linux 上非常流行的高级第三方同步工具。我们有篇对 Insync 支持 Google Drive 的详细点评文章。

而最近发布的 Insync 3 支持了 OneDrive。因此在本文中,我们将看下如何在 Insync 中使用 OneDrive 以及它的新功能。

非 FOSS 警告

少数开发者会对非 FOSS 软件引入 Linux 感到痛苦。作为专注于桌面 Linux 的门户,即使不是 FOSS,我们也会在此介绍此类软件。

Insync 3 既不是开源软件,也不免费使用。你只有 15 天的试用期进行测试。如果你喜欢它,那么可以按每个帐户终生 29.99 美元的费用购买。

我们不会拿钱来推广它们(以防你这么想)。我们不会在这里这么做。

在 Linux 中通过 Insync 获得原生 OneDrive 体验

尽管它是一个付费工具,但依赖 OneDrive 的用户或许希望在他们的 Linux 系统中获得同步 OneDrive 的无缝体验。

首先,你需要从官方页面下载适合你 Linux 发行版的软件包。

你也可以选择添加仓库并进行安装。你将在 Insync 的官方网站看到说明。

安装完成后,只需启动并选择 OneDrive 选项。

另外,要注意的是,你添加的每个 OneDrive 或 Google Drive 帐户都需要单独的许可证。

现在,在授权 OneDrive 帐户后,你必须选择一个用于同步所有内容的基础文件夹,这是 Insync 3 中的一项新功能。

Insync 3 Base Folder

除此之外,设置完成后,你还可以选择性地同步本地或云端的文件/文件夹。

Insync Selective Sync

你还可以通过添加自己的规则来自定义同步选项,以忽略/同步所需的文件夹和文件,这完全是可选的。

Insync Customize Sync Preferences

最后,就这样完成了。

Insync 3

你现在可以在包括带有 Insync 的 Linux 桌面在内的多个平台使用 OneDrive 开始同步文件/文件夹。除了上面所有新功能/更改之外,你还可以在 Insync 上获得更快/更流畅的体验。

此外,借助 Insync 3,你可以查看同步进度:

总结

总的来说,对于希望在 Linux 系统上同步 OneDrive 的用户而言,Insync 3 是令人印象深刻的升级。如果你不想付款,你可以尝试其他 Linux 的免费云服务

你如何看待 Insync?如果你已经在使用它,到目前为止的体验如何?在下面的评论中让我们知道你的想法。


via: https://itsfoss.com/use-onedrive-on-linux/

作者:Ankush Das 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

查找并排除你存储在 AWS 和 GitHub 中的数据里的漏洞。

如果你的日常工作是开发者、系统管理员、全栈工程师或者是网站可靠性工程师(SRE),工作内容包括使用 Git 从 GitHub 上推送、提交和拉取,并部署到亚马逊 Web 服务上(AWS),安全性就是一个需要持续考虑的一个点。幸运的是,开源工具能帮助你的团队避免犯常见错误,这些常见错误会导致你的组织损失数千美元。

本文介绍了四种开源工具,当你在 GitHub 和 AWS 上进行开发时,这些工具能帮助你提升项目的安全性。同样的,本着开源的精神,我会与三位安全专家——Travis McPeak,奈飞高级云安全工程师;Rich Monk,红帽首席高级信息安全分析师;以及 Alison Naylor,红帽首席信息安全分析师——共同为本文做出贡献。

我们已经按场景对每个工具都做了区分,但是它们并不是相互排斥的。

1、使用 gitrob 发现敏感数据

你需要发现任何出现于你们团队的 Git 仓库中的敏感信息,以便你能将其删除。借助专注于攻击应用程序或者操作系统的工具以使用红/蓝队模型,这样可能会更有意义,在这个模型中,一个信息安全团队会划分为两块,一个是攻击团队(又名红队),以及一个防守团队(又名蓝队)。有一个红队来尝试渗透你的系统和应用要远远好于等待一个攻击者来实际攻击你。你的红队可能会尝试使用 Gitrob,该工具可以克隆和爬取你的 Git 仓库,以此来寻找凭证和敏感信息。

即使像 Gitrob 这样的工具可以被用来造成破坏,但这里的目的是让你的信息安全团队使用它来发现无意间泄露的属于你的组织的敏感信息(比如 AWS 的密钥对或者是其他被失误提交上去的凭证)。这样,你可以修整你的仓库并清除敏感数据——希望能赶在攻击者发现它们之前。记住不光要修改受影响的文件,还要删除它们的历史记录

2、使用 git-secrets 来避免合并敏感数据

虽然在你的 Git 仓库里发现并移除敏感信息很重要,但在一开始就避免合并这些敏感信息岂不是更好?即使错误地提交了敏感信息,使用 git-secrets 可以避免你陷入公开的困境。这款工具可以帮助你设置钩子,以此来扫描你的提交、提交信息和合并信息,寻找常见的敏感信息模式。注意你选择的模式要匹配你的团队使用的凭证,比如 AWS 访问密钥和秘密密钥。如果发现了一个匹配项,你的提交就会被拒绝,一个潜在的危机就此得到避免。

为你已有的仓库设置 git-secrets 是很简单的,而且你可以使用一个全局设置来保护所有你以后要创建或克隆的仓库。你同样可以在公开你的仓库之前,使用 git-secrets 来扫描它们(包括之前所有的历史版本)。

3、使用 Key Conjurer 创建临时凭证

有一点额外的保险来防止无意间公开了存储的敏感信息,这是很好的事,但我们还可以做得更好,就完全不存储任何凭证。追踪凭证,谁访问了它,存储到了哪里,上次更新是什么时候——太麻烦了。然而,以编程的方式生成的临时凭证就可以避免大量的此类问题,从而巧妙地避开了在 Git 仓库里存储敏感信息这一问题。使用 Key Conjurer,它就是为解决这一需求而被创建出来的。有关更多 Riot Games 为什么创建 Key Conjurer,以及 Riot Games 如何开发的 Key Conjurer,请阅读 Key Conjurer:我们最低权限的策略

4、使用 Repokid 自动化地提供最小权限

任何一个参加过基本安全课程的人都知道,设置最小权限是基于角色的访问控制的最佳实现。难过的是,离开校门,会发现手动运用最低权限策略会变得如此艰难。一个应用的访问需求会随着时间的流逝而变化,开发人员又太忙了没时间去手动削减他们的权限。Repokid 使用 AWS 提供提供的有关身份和访问管理(IAM)的数据来自动化地调整访问策略。Repokid 甚至可以在 AWS 中为超大型组织提供自动化地最小权限设置。

工具而已,又不是大招

这些工具并不是什么灵丹妙药,它们只是工具!所以,在尝试使用这些工具或其他的控件之前,请和你的组织里一起工作的其他人确保你们已经理解了你的云服务的使用情况和用法模式。

应该严肃对待你的云服务和代码仓库服务,并熟悉最佳实现的做法。下面的文章将帮助你做到这一点。

对于 AWS:

对于 GitHub:

同样重要的一点是,和你的安全团队保持联系;他们应该可以为你团队的成功提供想法、建议和指南。永远记住:安全是每个人的责任,而不仅仅是他们的。


via: https://opensource.com/article/19/9/open-source-cloud-security

作者:Alison Naylor,Anderson Silva 选题:lujun9972 译者:hopefully2333 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出