apt purge đã gỡ VPN nhưng dịch vụ vẫn khởi động khi boot
apt purge xóa tệp của gói, không xóa unit mà script của nhà cung cấp đã cài. Xóa unit và liên kết wants của nó, rồi chọn một chủ sở hữu khởi động duy nhất.
apt purge nói gói đã biến mất, vậy mà mỗi lần khởi động vẫn có một đường hầm dựng lên. Journal tiếp tục lớn, các tuyến đường quay lại, và máy hành xử như thể chưa gỡ gì. Trình cài của nhà cung cấp có thể ghi những tệp mà trình quản lý gói chưa bao giờ ghi nhận, nên gỡ một gói và gỡ một sản phẩm là hai việc khác nhau. Runbook dưới đây tách hai bản ghi và kết thúc việc gỡ một cách có chủ đích.
Hai trình cài, hai bản ghi khác nhau
Gói Debian giữ một danh sách tệp, và purge xóa đúng những gì danh sách đó nêu tên cùng cấu hình của gói. Trình cài shell hoặc gói .run không giữ danh sách như vậy; nó ghi ở bất cứ đâu, thường vào /opt, /usr/local và /etc/systemd/system. Không đường nào trong số đó xuất hiện trong danh sách tệp của bất kỳ gói nào, nên dpkg không biết và không báo cáo chúng. Cuối cùng bạn có hai chủ sở hữu cài đặt trên một hệ thống tệp, và chỉ một trong số họ giữ sổ sách.
Hỏi dpkg về đường dẫn cụ thể trước khi xóa nó. Một đường dẫn mà nó từ chối là của bạn để gỡ, và cùng câu trả lời cho biết bản nâng cấp sau có đưa nó trở lại hay không.
dpkg -S /etc/systemd/system/acmevpn.service
systemctl list-unit-files | grep -i acmevpn
Một unit và liên kết wants của nó là hai tệp riêng
Kích hoạt là một hành động riêng so với cài đặt. Unit khai báo quan hệ đích trong phần [Install], và systemctl enable biến những khai báo đó thành liên kết tượng trưng trong thư mục .wants/ của mỗi đích. Giờ có hai đường: tệp unit và liên kết kéo nó vào một đích khởi động. Chỉ xóa tệp thì liên kết không trỏ vào đâu, điều này tạo ra khiếu nại khi khởi động; chỉ xóa liên kết thì unit vẫn khởi chạy được theo tên. Cả hai đều phải biến mất.
Gỡ chúng theo thứ tự rồi nạp lại, để systemd thôi giữ các định nghĩa cũ trong bộ nhớ.
systemctl disable --now acmevpn.service
systemctl show -p FragmentPath -p ExecStart acmevpn.service
sudo rm /etc/systemd/system/acmevpn.service
sudo rm /etc/systemd/system/multi-user.target.wants/acmevpn.service
systemctl daemon-reload
Đọc FragmentPath thay vì đoán vị trí, vì nhà cung cấp có thể đã ghi vào /usr/lib/systemd/system hoặc /lib/systemd/system chứ không phải /etc. Xóa bản sao bạn mong đợi để bản đang có hiệu lực tiếp tục chạy, và bản sửa trông như thành công cho đến lần nạp lại tiếp theo. Liệt kê lại các tệp unit sau khi nạp xong, và xác nhận tên không còn xuất hiện.
Tìm tệp nhị phân giữ cho cách bố trí này sống
Một unit đã kích hoạt tiếp tục khởi động tiến trình nền bất kể cơ sở dữ liệu gói tin nghĩ gì. Tiến trình đó có thể đưa đường hầm trở lại, thêm tuyến đường lần nữa hoặc khôi phục một quy tắc kill-switch, và hành vi trông như siêu nhiên cho đến khi bạn xem xét cách bố trí. Đi theo đường dẫn ExecStart và kiểm tra xem tệp nhị phân còn ở đó không, vì một tệp thực thi bị bỏ lại dưới /opt là tất cả những gì cách bố trí cần. Xóa unit dừng việc khởi động theo lịch; nó không xóa chương trình.
Đối xử với các thư mục trạng thái bằng sự cẩn trọng tương tự. Token tài khoản, hồ sơ được tạo và danh sách máy chủ trong bộ nhớ đệm sống dưới /var/lib hoặc trong thư mục nhà, và đó là thông tin xác thực, không phải bộ nhớ đệm vứt đi. Gỡ chúng sau khi dịch vụ dừng, một cách có chủ đích, và ghi lại những gì bạn đã lấy.
sudo ls -l /opt/acmevpn /usr/local/bin/acmevpn
sudo find /var/lib -maxdepth 2 -iname "*acme*"
systemctl is-enabled acmevpn.service
Chọn một chủ sở hữu khởi động và thử nó
Ba ứng viên có thể đòi quyền khởi động, và cài cả ba tạo ra một cuộc đua chứ không phải bảo vệ kép. Tệp tự khởi động của màn hình nền chỉ chạy sau khi ai đó đăng nhập, một unit systemd chạy sớm hơn nhưng cần một ứng dụng khách hoạt động không màn hình, và một mục cron @reboot kích hoạt theo lịch có thể sai với ứng dụng khách mạng. CLI của nhà cung cấp có thể còn yêu cầu một đối số máy chủ, vì khi khởi động không có phiên trước để tiếp tục. Chọn ứng viên phù hợp với cách ứng dụng khách xác thực, và bỏ những cái khác.
Thử bằng cách khởi động lại máy và nhìn vào ba sự thật độc lập: trạng thái unit, danh sách tiến trình, và một kết nối mới tới thứ bạn có thể xác minh. Một ứng dụng khách cần móc khóa hoặc đăng nhập tương tác sẽ thất bại khi khởi động dù có tệp unit đúng, và journal nói vậy nếu bạn đọc nó thay vì chỉ trạng thái dịch vụ.
Hoặc cấp cho ứng dụng khách một thông tin xác thực hoạt động mà không hỏi, hoặc khởi chạy nó khi đăng nhập. Cả hai đều có lý, và kết hợp chúng là cách một đường hầm có được hai chủ sở hữu tranh nhau nó.
Ghi lại điều lần purge tiếp theo nên mong đợi
Ghi hai sự thật sau mỗi lần gỡ thủ công: trình cài nào đã tạo ra cách bố trí này, và chủ sở hữu nào đang khởi chạy nó. Ghi chú đó biến lần purge tiếp theo từ bất ngờ thành một mục trong danh sách kiểm tra, và nó sống lâu hơn người đã làm việc đó.
Giữ nó bên cạnh cấu hình dịch vụ chứ không phải trong thư mục cá nhân, và ghi ngày, vì bản cập nhật của nhà cung cấp có thể khôi phục một unit bạn đã xóa. So sánh systemctl list-unit-files với ghi chú đó vài tháng một lần sẽ bắt được việc khôi phục khi việc sửa vẫn còn rẻ.