💻
Notes-CS
  • INTRO
  • 操作系统
    • 操作系统原理
      • 操作系统概述
        • 操作系统的分类
          • 批处理操作系统
          • 分时操作系统
          • 实时操作系统
          • 个人计算机操作系统
          • 网络操作系统
          • 分布式操作系统
          • 嵌入式操作系统
        • 操作系统的运行环境与机制
          • 中断与异常
          • 系统调用
      • 进程与线程
        • 进程
        • 线程
        • 协程
      • 处理器调度
      • 同步机制
      • 存储模型
      • 文件系统
        • 分区类型
      • 输入输出系统
    • 通用操作系统
      • GNU/Linux
        • Linux 内核
          • Linux 启动过程
          • 几种内核映像的区别
          • 终端设备
          • Ptrace
        • 可执行文件 ELF
        • 文件系统
          • swap
          • Linux 文件系统目录描述
          • 特殊文件
        • 软件生态
          • 基于 Linux 的 OS
            • Arch Linux
            • CentOS
            • Debian
            • Fedora
            • Gentoo
            • Kali
            • OpenSUSE
            • OpenWRT
            • Ubuntu
          • 桌面环境
            • KDE
            • GNOME
            • Xfce
            • DDE
            • Unity
            • MATE
          • 包管理器
            • apt
              • apt install
            • yum
            • pacman
        • Utils
          • dd
          • motd
          • 系统状态分析工具
          • TTY和PTS
          • SysVInit 与 SystemD
          • Linux 系统参考手册
          • 文本IO处理
            • awk
            • sed
            • cut
            • grep
            • xargs
            • diff & patch
      • MacOS
        • Darwin 内核
        • 快捷键
      • Windows
        • NT 内核
        • 可执行文件 PE
        • 文件系统组织
        • 发行版本
          • 古董
            • Windows 3.1
            • Windows 95
            • Windows 98
            • Windows 2000
            • Windows me
            • Windows Vista
            • Windows 8
          • Windows XP
          • Windows 7
          • Windows 10
            • 常用快捷键
      • Android
        • 系统结构
        • 软件包格式 APK
        • 版本历史
    • 通用系统概念
      • ANSI转义序列
        • 终端颜色控制符
      • POSIX
      • 虚拟化
        • 常见虚拟化OS镜像格式
      • Secure Boot
      • 常见文件系统
        • NTFS
        • FAT
        • JFFS
        • tmpfs
  • 编程
    • 编程语言
      • C
        • 语法
          • const
          • typedef
        • 库
          • C standard library(libc)
            • glibc
              • ptrace
          • C POSIX library
            • pthread
        • GNU C
        • 其它
          • 链接库的构成
          • 头文件规范
          • 动态链接库
      • C++
        • 语法
        • 库
          • SL/STL
            • 容器
              • vector
              • string
              • unordered_map
            • 迭代器
            • 其它
              • man page 解决方案
        • 面向对象
          • 重写与重载
            • 运算符重载
      • Python
        • 语法
        • 包
          • 内建
          • 第三方
            • requests
        • 其它
          • PyPI 的使用
          • 内建模块
      • Rust
        • 入门实例
      • Java
      • shell
        • set
    • 数据结构与算法
      • 数据结构
        • 栈
        • 队列
        • 链表
        • 哈希表
        • 并查集
        • 堆
        • 树
          • 二叉树
        • 图
      • 算法
        • 算法基础
          • 枚举
          • 模拟
          • 递归 & 分治
          • 贪心
          • 排序
        • 搜索
        • 动态规划
        • 字符串
        • 数学
          • 快速幂
        • 图论
    • 编译原理
      • 编译器与解释器
      • 词法分析
      • 语法分析
      • 类型检查
      • 中间代码生成
      • 目标代码生成
      • 代码优化
    • 软件工程
      • 编程范式
        • 指令式
          • 过程式
          • 块结构
          • 结构化
          • 非结构化
          • 递归
          • 模块化
        • 面向对象
          • 基于类
          • 基于原型
        • 声明式
          • 函数式
            • 纯函数式
            • 函数响应
        • 多态
          • 多分派
          • 泛型
            • 模板
        • 元编程
          • 宏
          • 元类
          • 反射式
      • 开发方法
        • 敏捷开发
        • 过程模型
          • 瀑布模型
          • V 模型
          • 增量模型
          • 螺旋模型
      • 开发流程
        • 问题定义
        • 可行性研究
        • 需求分析
        • 概要设计
        • 详细设计
        • 编码与测试
        • 运行与维护
      • 开源软件
        • 版本后缀规则
        • 开源协议
          • GPL
          • LGPL
          • MIT
          • BSD
          • Apache
          • Mozilla
  • 信息安全
    • 信息安全原理
      • IoT
        • 交叉编译
        • 固件格式
        • 常见协议
          • UPnP
      • 二进制
        • 常见漏洞
          • Stack Overflow
          • Format String Bug
          • Integer Overflow
          • Double Free
          • Use After Free
          • Race Condition
        • 通用工具
          • IDA
          • ghidra
          • pwntools
          • binutils
          • GDB
          • 脚本工具
            • LibcSearcher
            • main_arena_offset
            • one_gadget
            • ROPgadget
        • 常用技术
          • 符号执行
            • 传统符号执行
            • 现代符号执行
          • 模糊测试
      • Web
        • 常见漏洞
          • SQLi - SQL injection
          • XSS - Cross Site Scripting
            • 基本原理
          • CSRF - Cross Site Request Forgery
          • SSRF - Server-Side Request Forgery
          • XXE - XML External Entity
            • 基本原理
        • 通用工具
          • Burp Suite
          • Wireshark
      • 密码学
        • 流密码
          • XOR
          • RC4
        • 分组密码
          • DES - Data Encryption Standard
          • AES - Advanced Encryption Standard
        • 公钥密码
          • RSA
            • 欧几里得算法
            • 扩展欧几里得算法
            • 中国剩余定理
            • 共模攻击
          • 椭圆曲线算法
        • 数字签名
        • 数据校验
          • CRC
      • 区块链
        • 以太坊
    • 信息安全实践
      • 环境准备
        • IOT
          • 固件获取
          • 固件打包与解包
          • QEMU 模拟
          • 交叉编译
          • 制作文件系统镜像
          • UART 调试
      • 漏洞挖掘
        • 漏洞概览
          • 漏洞编号与管理机构
        • 漏洞挖掘技术
          • 静态分析
          • 模糊测试
            • 工具与框架
              • AFL
          • 污点分析
          • 符号执行
            • 工具与框架
              • Angr
              • KLEE
              • S2E
      • 安全开发
      • 渗透测试
        • shell
        • 网络空间测绘系统
          • quake
          • shodan
        • 内网渗透
          • Linux 靶机
            • 信息搜集
            • 持久化
            • 痕迹清理
        • 工具与框架
          • Metasploit
    • 论文与演示
  • Web 与计算机网络
    • 协议栈
      • 链接层
        • PPP
        • ARP
        • MAC
      • 网络层
        • IP - Internet Protocol
          • IPv4
            • IPv4 分级式寻址
            • IPv4 私有地址划分
          • IPv6
        • ICMP - Internet Control Message Protocol
      • 传输层
        • TCP
        • UDP
        • TLS/SSL
      • 应用层
        • UPnP
        • HTTP
        • DNS
        • FTP
    • Web
      • 浏览器
        • Chrome
          • 内建功能
          • 快捷键
        • Tor
      • Web容器
        • Apache
        • Nginx
        • lighttpd
      • CGI
      • MIME type
      • 搜索引擎
  • 体系结构与硬件
    • 计算机体系结构
      • 指令集
        • X86
        • AMD64
        • ARM
        • RISC-V
        • MIPS
    • 设备与接口
      • 接口协议
        • UART
        • USB
        • HDMI
        • PCI
      • 存储设备
        • 固态硬盘
          • 闪存颗粒 ?LC
        • 识别 Linux上的设备(磁盘)类型
        • 字符设备与块设备
        • MTD
      • 网络设备
        • 路由器
        • 交换机
        • 网卡与虚拟网卡
        • 光接入网络
          • 光猫
  • 数学
    • 离散数学
    • 线性代数
    • 概率与统计
    • 计算理论
  • 软件与框架
    • 通用
      • bash
      • Vim
        • 配置
        • 快捷键
        • 插件
        • VIM Script
      • git
      • Tmux
      • gdb
      • ssh
      • make
      • 双拼
    • 专用
      • 🪜Untitled
        • clash
      • gcc
      • nmap
      • QEMU
        • QEMU source
        • 模拟 raw Linux
        • 模拟发行版
      • docker
      • buildroot
      • burpsuite
    • 轮子
      • LaTeX
      • LLVM
      • libpcap
  • reCTF
    • PWN
      • QEMU PWN
      • Kernel PWN
    • Web
    • Reverse
    • Crypto
    • MISC
  • 资源
    • 学习站
      • 安全学习站
        • 门户
        • 论坛
        • 教程
        • 会议
        • 博客
      • 编程学习站
        • 文档
    • 工具站
      • 安全工具站
        • 二进制
        • Web
        • IoT
        • 社工
      • 应用工具站
  • 实践记录
    • 事件
      • 对于 UDPt 漏洞的跟踪实践
    • 编译
      • alware 静态交叉编译
      • buildroot 编译 arm target
由 GitBook 提供支持
在本页
  • 痛点说明
  • 部署 mongodb
  • 结语
  1. 操作系统
  2. 通用操作系统
  3. GNU/Linux
  4. 软件生态
  5. 包管理器
  6. apt

apt install

上一页apt下一页yum

最后更新于3年前

痛点说明

当我们在使用 debian/ubuntu 的时候,如果需要安装一些应用,通常会执行 sudo apt install ...,如果源中有的话,这是最傻瓜式,也最方便的方式了。

但是笔者其实一直不是很喜欢这种方式,原因如下:

  1. 这种方式由于给到了 root 权限,无形中,背后做了很多事,对于笔者来说,总感觉缺乏一些掌控

  2. 这种方式安装的软件,相关的文件会分散到各种目录,很乱。

  3. 没法精确的去控制到底使用哪个版本,因为源中可能没有。

为什么乱呢? 这和 Linux 的设计有关。这块笔者不是很清晰,之前看过一片 ,这篇文章很长,它后面简要介绍了 Linux 上安装软件的特点,强烈建议玩 Linux 的同学看下。这里,我简单描述下,希望我理解的没有问题。 我们先说下 Windows。 在 Windows 下,安装一个软件,通常会是一个安装包,点击安装,会指定一个安装目录,安装完成后,这个软件连同这个软件的相关依赖,都会同时放进我们指定的安装目录。 当然,如果是那种解压直接用的,直接找个目录放解压就好。这个时候,是不是很清晰,某个软件就是安装在某个目录。当然,除此外,然后也有可能在 比如 User 目录下,放一些配置文件,缓存什么的。但是笔者以为,相比较 Linux,可以说相当清爽。 反观 Linux 呢? 当我们执行 sudo apt install ... 时,最终文件会散落到 /usr、/var、/run 、/etc等等这些目录,如果你是个小白,可能对此完全蒙圈,即便对于一些开发人员,其实对这些也知之不多。只有对于有经验的运维人员,才能快速熟练的找到相关文件的位置。

我们从 Linux 上面软件的安装方式出发,其实就能窥见这其中的混乱了。 比如说 Ubuntu,当我们要安装一个软件时,通常会有几种安装方式:

  1. sudo apt install ...

  2. sudo dpkg -i ***.deb

  3. snap install ...

  4. 如果是桌面版的话,可以直接从应用商店下载

  5. 下载二进制文件压缩包,解压直接使用

  6. 下载源码,自行编译,再 make install

所以,在使用 Linux 的时候,我们总会去搜索诸如 “Ubuntu18.04 如何安装 mongodb ” 这样的问题,而且经常是一个软件有几种不同的安装方式,对于初学者,当从其中一个点出发的时候,基本是蒙圈的。与此同时,我们在使用 Windows 完全不会有这样的困扰,管你是 QQ,PS 还是 mysql,基本上通过一个安装包解决问题。

下面我们来梳理下混乱之下到底是些什么? 以下描述基于 Ubuntu18.04 安装 redis 为例, 当我们执行 sudo apt install redis 的时候,系统做了如下事件:

  1. 创建了 redis user 和 redis group, 同时指定其 home 为 /var/lib/redis,我们 执行 cat /etc/passwd | grep redis, 看到以下结果,注意该用户无法登录系统

    redis:x:124:129::/var/lib/redis:/usr/sbin/nologin
  1. 添加了 /etc/init.d/redis-server 的可执行脚本

  2. 添加了 /etc/rcx.d/S01redis-server 的软链

  3. 添加了 /lib/systemd/system//redis-server.service 文件,供 systemd 调度

  4. 添加了 /etc/systemd/system/multi-user.target.wants/redis-server.service -> /lib/systemd/system/redis-server.service 的软链,用于开机启动

  5. 将 redis-server、redis-cli 等命令 放到 /usr/bin 目录下

  6. 启动 redis-server 服务,这个时候会关联一下目录

    • /etc/redis/redis.conf redis 默认配置文件

    • /var/lib/redis redis 用户家目录,默认情况下,redis 的数据会放在这里

    • /var/log/redis 默认 redis 的日志会放在这里

    • /run/redis.pid 默认 redis daemon 的 pid 放在这里

如果这个软件按照规范来的话,通常是做了这些事情。当然不同的软件会有所差别,这个差别可能是未知的,你如果想要搞明白,需要去花好多时间研究。

作为一个工程师,笔者以为信心源于全面的测试和对细节的掌控,所以以上的安装方式,我其实是惧怕的。 出于以上种种原因吧,笔者更倾向于下载二进制文件解压,尽量像在 Windows 下,采用单一目录安装。其实这种安装方式,在 Linux 下也越发的常见了,比如 hadoop 生态组件,比如 elasticsearch 生态的组件,都是采用这种方式安装的。 我们来看下两种安装方式目录结构的区别

apt install 的方式,这种方式将应用程序相关文件拆开,放到 Linux 下的各种目录下,其实这种方式我觉得类似于将一个项目完全从纯技术角度分包,当项目小的时候还好,但是项目很大时,一切都会变得恶心。目录结构如下:

# tree /var/log
/var/log
├── redis
│   └── redis-server.log
├── mongod
│   └── mongod.log

# tree /var/lib
/var/lib
├── redis
│   └── .bashrc
├── mongod
│   └── .bashrc

# tree /run
/run
├── redis
│   └── redis.pid
├── mongod
│   └── mongod.pid


# tree /etc
/etc
├── redis
│   └── redis.conf
├── mongod
│   └── mongod.conf

第二种方式是先将某软件相关的文件聚合到自己的目录下,然后在自己的目录下,从技术角度再分包。我们采用这种方式组织文件。其实也体现了内聚的思想。类似于,将整个项目根据不同的 feature,先分包,然后在 feature 包内,再从技术角度出发细分。如果项目足够复杂,当然这种是更好的。其目录结构如下:

# tree /opt
/opt
├── redis
│   ├── data
│   │   └── redis.data
│   ├── logs
│   │   └── redis.log
│   ├── redis.conf
│   ├── redis.pid
├── mongodb
    ├── data
    │   └── mongod.data
    ├── logs
    │   └── mongod.log
    ├── mongod.conf
    ├── mongod.pid

部署 mongodb

  1. 该软件整体安装在 /opt 目录下

  2. 相关的可执行文件如 mongo、mongod 全局可用

  3. 配置到系统服务,可开机启动

了解了以上思路,我们正式开始部署流程,注意以下所有操作都是在 root 账户下,后面不再赘述。

1. 先解压从官网下载的二进制文件包,在 /opt 目录下解压后,解压后文件目录如下

# tree /opt
/opt
└── mongodb-linux-x86_64-3.6.4
    ├── bin
    │   ├── bsondump
    │   ├── install_compass
    │   ├── mongo
    │   ├── mongod
    │   ├── mongodump
    │   ├── mongoexport
    │   ├── mongofiles
    │   ├── mongoimport
    │   ├── mongoperf
    │   ├── mongoreplay
    │   ├── mongorestore
    │   ├── mongos
    │   ├── mongostat
    │   └── mongotop
    ├── GNU-AGPL-3.0
    ├── MPL-2
    ├── README
    └── THIRD-PARTY-NOTICES

2. 创建相关文件及文件夹

# 进入到 mongodb 安装目录
cd /opt/mongodb-linux-x86_64-3.6.4

# 创建将来存放 mongo 数据的文件夹
mkdir data 

# 创建日志文件夹
mkdir logs

# 创建并编写配置文件
vim mongod.conf

# 创建并编写 mongod.service, 用于将来注册进 systemd
vim mongod.service

配置文件 mongod.conf 内容如下

# mongod.conf
# Where to store the data.
dbpath = /opt/mongodb/data
storageEngine = wiredTiger
directoryperdb = true

# where to log
logpath = /opt/mongodb/logs/mongodb.log
logappend=true
logRotate = reopen

port = 27017

# daemon
fork = true

# Enable journaling, http://www.mongodb.org/display/DOCS/Journaling
journal=true

# Turn on/off security.  Off is currently the default
noauth = true
# auth = true
# keyFile = /srv/mongodb/conf/rs.key

# crawler repl
# replSet=rs_crawler

pidfilepath = /opt/mongodb/mongod.pid

Service 配置文件 mongod.service 内容如下

# mongod.service
[Unit]
Description=mongodb server
After=network.target

[Service]
Type=simple
User=mongodb
Group=mongodb
SyslogIdentifier=mongodb
LimitNOFILE=65536
ExecStart=/opt/mongodb/bin/mongod -f /opt/mongodb/mongod.conf
ExecStop=/bin/kill -s TERM $MAINPID
PIDFile=/opt/mongodb/mongod.pid
Restart=always

[Install]
WantedBy=multi-user.target

3. 接下来为了解耦或是方便,我们可以创建一些软链接

ln -s /opt/mongodb-linux-x86_64-3.6.4 /opt/mongodb
ln -s /opt/mongodb-linux-x86_64-3.6.4/bin/mongod /usr/local/bin/mongod
ln -s /opt/mongodb-linux-x86_64-3.6.4/bin/mongo /usr/local/bin/mongo

# /opt/mongodb-linux-x86_64-3.6.4/bin 下的其它命令是否创建软链,根据自己需求

我们注意到,mongodb 的所有相关文件都在自己的目录内,如果外部引用的话,都是通过软链接的方式,这类似于设计模式中的桥接或是代理。

完成以上步骤后, 执行 mongod -f /opt/mongodb/mongod.conf, 启动 mongodb,如果一切正常的话,mongodb 正常启动,此时目录结构如下,所有相关的内容全部聚合到一个目录下。

怎么样,很清晰吧 O(∩_∩)O

# tree /opt
/opt
├── mongodb -> mongodb-linux-x86_64-3.6.4
└── mongodb-linux-x86_64-3.6.4
    ├── bin
    │   ├── bsondump
    │   ├── install_compass
    │   ├── mongo
    │   ├── mongod
    │   ├── mongodump
    │   ├── mongoexport
    │   ├── mongofiles
    │   ├── mongoimport
    │   ├── mongoperf
    │   ├── mongoreplay
    │   ├── mongorestore
    │   ├── mongos
    │   ├── mongostat
    │   └── mongotop
    ├── data
    │   ├── admin
    │   │   ├── collection-0--3307101973996970816.wt
    │   │   └── index-1--3307101973996970816.wt
    │   ├── diagnostic.data
    │   │   ├── metrics.2019-10-15T11-05-02Z-00000
    │   │   └── metrics.2019-10-15T11-05-20Z-00000
    │   ├── journal
    │   │   ├── WiredTigerLog.0000000002
    │   │   ├── WiredTigerPreplog.0000000001
    │   │   └── WiredTigerPreplog.0000000002
    │   ├── local
    │   │   ├── collection-2--3307101973996970816.wt
    │   │   └── index-3--3307101973996970816.wt
    │   ├── _mdb_catalog.wt
    │   ├── mongod.lock
    │   ├── sizeStorer.wt
    │   ├── storage.bson
    │   ├── WiredTiger
    │   ├── WiredTigerLAS.wt
    │   ├── WiredTiger.lock
    │   ├── WiredTiger.turtle
    │   └── WiredTiger.wt
    ├── GNU-AGPL-3.0
    ├── logs
    │   └── mongodb.log
    ├── mongod.conf
    ├── mongod.pid
    ├── mongod.service
    ├── MPL-2
    ├── README
    └── THIRD-PARTY-NOTICES

通过 mongod -f /opt/mongodb/mongod.conf 启动的服务在后台运行,通过 ps 找到 pid 先将其杀掉,然后进行下一步,否则会导致后续配置失败。

4. 注册到系统服务

# 创建 mongodb 的用户,通常这种系统服务,出于安全考虑,我们不会直接以 root 用户运行
# 我们首先创建一个 mongodb 用户,将来用这个用户运行 mongodb
# 下面的命令创建了 mongodb user,同时创建了 mongodb group,指定该用户无法登录系统,同时创建了家目录,此处家目录其实可以不创建,因为我们的部署流程中没用到 mongodb 的家目录
useradd mongodb --home-dir /var/lib/mongodb --shell /usr/sbin/nologin --create-home --user-group

# 将 mongodb 的安装目录 全部交给 mongodb 用户
chown -R mongodb:mongodb /opt/mongodb /opt/mongodb-linux-x86_64-3.6.4

# 将 service 文件软链到 /lib/systemd/system, 注册成系统服务
ln -s /opt/mongodb/mongod.service /lib/systemd/system/mongod.service
# 重载 systemd 列表
systemctl daemon-reload

# 清除掉刚刚启动 mongodb 在安装目录下创建的文件,因为刚才是以 root 用户启动的,里面创建的文件都属于 root,不删除的话,服务起不来
rm -rf /opt/mongodb/mongod.pid /opt/mongodb/logs/* /opt/mongodb/data/* 

# 开启服务, 如果一切正常,显示如下
systemctl start mongod.service

    ● mongod.service - mongodb server
       Loaded: loaded (/opt/mongodb/mongod.service; disabled; vendor preset: enabled)
       Active: active (running) since Tue 2019-10-15 19:29:10 CST; 2s ago
     Main PID: 21850 (mongod)
        Tasks: 23 (limit: 478)
       CGroup: /system.slice/mongod.service
               └─21850 /opt/mongodb/bin/mongod -f /opt/mongodb/mongod.conf

    Oct 15 19:29:10 iZ8vb9wvg14ypn9rjj3sdpZ systemd[1]: Started mongodb server.

# 设置开机启动
systemctl enable mongod.service

结语

下面,我们以 mongodb 为例,在 Ubuntu18.04 上详细的走一遍流程。mongodb 官方提供了二进制文件下载,。 下面我先说下我自己的部署标准

至此,我们尽量模拟了 apt install ... 的方式部署好了 mongodb,并逐步拆解成单一步骤,感觉一切尽在掌握。 但是其实,其中还是有些不同的。 上面我们在注册系统服务的时候提到了 systemd, init.d, 还用到了 systemctl 命令, 这到底是什么呢? 其中的不同恰好涉及到这些知识点,我们 详细说明。

文章
在这里
下篇文章