总结Ubuntu中常用操作场景
Ubuntu 软件源更换为清华源
cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak
Types: deb
URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu/
Suites: noble noble-updates noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
apt-get update
Ubuntu 机器基础准备
安装 JDK
sudo apt install -y openjdk-17-jdk
为 Ubuntu 系统创建具有 sudo 的一般用户
# 新增用户
sudo adduser ubuntu
# 将用户加入 sudo 组
sudo usermod -aG sudo ubuntu
安装 tmux
sudo apt update
sudo apt install tmux -y
Linux 安装配置执行 APP SOP
新建 APP 隔离运行用户
sudo useradd -r -s /usr/sbin/nologin -d /nonexistent -U -M myapp
# -r 系统账号 -s nologin 禁止登录 -U 同时建组 -M 不建 home
解压软件到及创建标准化目录
myapp.py
#!/usr/bin/env python3
"""
极简 Web 服务器 —— 返回指定配置文件的全部内容(日志级别对齐版)
用法:
python mini_server.py \
--host 0.0.0.0 \
--port 8080 \
--config /path/to/file.txt \
--log-level INFO
"""
import argparse
import logging
from http.server import BaseHTTPRequestHandler, HTTPServer
def setup_logging(level: str) -> None:
"""初始化日志格式与级别,级别固定 8 字符宽度左对齐"""
logging.basicConfig(
level=getattr(logging, level.upper(), logging.INFO),
format="[%(asctime)s] [%(levelname)-8s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
def read_file(path: str) -> bytes:
"""读取配置文件全部内容,以二进制返回"""
logging.debug("Reading config file: %s", path)
with open(path, "rb") as f:
return f.read()
class Handler(BaseHTTPRequestHandler):
def __init__(self, file_path: str, *args, **kwargs):
self.file_path = file_path
super().__init__(*args, **kwargs)
def do_GET(self):
"""仅支持 GET,返回配置文件内容"""
logging.info("GET %s from %s", self.path, self.client_address[0])
try:
body = read_file(self.file_path)
self.send_response(200)
self.send_header("Content-Type", "text/plain; charset=utf-8")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
logging.debug("Response sent (%d bytes)", len(body))
except Exception as e:
logging.exception("Error handling GET")
self.send_error(500, str(e))
def log_message(self, fmt, *args):
"""覆盖父类日志,统一到 logging 模块"""
logging.info("%s - %s", self.address_string(), fmt % args)
def main():
parser = argparse.ArgumentParser(description="myapp")
parser.add_argument("--host", default="127.0.0.1", help="监听 IP (默认 127.0.0.1)")
parser.add_argument("--port", type=int, default=8000, help="监听端口 (默认 8000)")
parser.add_argument("--config", required=True, help="配置文件路径")
parser.add_argument(
"--log-level",
default="INFO",
choices=["DEBUG", "INFO", "WARNING", "ERROR"],
help="日志级别 (默认 INFO)",
)
args = parser.parse_args()
setup_logging(args.log_level)
handler = lambda *a, **kw: Handler(args.config, *a, **kw)
server = HTTPServer((args.host, args.port), handler)
logging.info("Serving on http://%s:%d/ (Ctrl-C 退出)", args.host, args.port)
try:
server.serve_forever()
except KeyboardInterrupt:
logging.info("Shutting down")
if __name__ == "__main__":
main()
# 1. 创建目录
mkdir -p /usr/local/myapp /etc/myapp /var/lib/myapp /var/log/myapp /run/myapp
# 2. 提前给属主(保证后续解压继承)
chown -R myapp:myapp /usr/local/myapp /etc/myapp /var/lib/myapp /var/log/myapp /run/myapp
# 3. 解压
tar -zxvf myapp.tar.gz -C /usr/local/myapp
# 4. 权限
sudo chmod -R 755 /usr/local/myapp /etc/myapp /run/myapp
sudo chmod -R 750 /var/lib/myapp /var/log/myapp
APP 配置文件
myapp.cfg
Welcome to myapp!!!
chmod 640 /etc/myapp/myapp.cfg
systemd 单元配置
/etc/systemd/system/myapp.service
# /etc/systemd/system/myapp.service
[Unit]
# 服务描述
Description = myapp
# 依赖
# network-online.target 是网络在线
# nss-lookup.target 是 NSS 就绪
# 弱依赖,服务启动之前启动但启动失败不会影响服务本身。
Wants = network-online.target
# 强依赖,服务在强依赖之后启动,若强依赖启动失败则服务无法启动
After = network-online.target nss-lookup.target
# 30 秒内最多重启 3 次
StartLimitIntervalSec = 30
StartLimitBurst = 3
[Service]
# 启动方式
Type = simple
# 运行用户
User = myapp
# 运行组
Group = myapp
# 启动执行命令
ExecStart = /usr/bin/python3 /usr/local/myapp/myapp.py \
--host 0.0.0.0 --port 8080 \
--config /etc/myapp/myapp.cfg \
--log-level DEBUG
# 平滑重载配置,此处是发送 SIGHUP 信号,如何重载需要由应用程序处理该型号并实现具体逻辑
ExecReload = /bin/kill -HUP $MAINPID
# 异常退出才重启(exit 非 0)
Restart = on-failure
# 失败后 5 秒再试
RestartSec = 5s
# ---------- 安全加固 ----------
# 禁止进程及其子进程提权
NoNewPrivileges = true
# 除明确列出目录外,整个文件系统只读
ProtectSystem = strict
# 禁止访问 /home、/root、/run/user
ProtectHome = true
# 允许写日志、数据、运行时
ReadWritePaths = /var/log/myapp /var/lib/myapp /run/myapp
[Install]
# 开机随多用户模式启动
WantedBy = multi-user.target
使用 systemctl 控制 APP 声明周期
# 重新加载配置
sudo systemctl daemon-reload
sudo systemctl status myapp
# 设置开机自启
sudo systemctl enable --now myapp.service
# 看状态/日志
sudo systemctl status myapp
sudo journalctl -u myapp -f
elasticsearch-create-enrollment-token -s kibana
简单授权过程
sudo chown -R ubuntu:ubuntu /usr/local/myapp
sudo chmod -R 750 /usr/local/myapp