Tailscale là gì và hoạt động như thế nào?
Tìm hiểu Tailscale: WireGuard mã hóa kết nối giữa server, coordination server quản lý key và ACL, NAT traversal, DERP relay và threat model.
Tailscale là gì?
Tailscale là một VPN kết nối trực tiếp các máy với nhau thay vì định tuyến toàn bộ lưu lượng qua một gateway do bạn tự vận hành. Mỗi node chạy WireGuard, nên các packet được mã hóa từ server này đến server khác và không thành phần nào trên đường truyền có thể đọc được chúng. Một coordination server do Tailscale host xử lý việc giới thiệu các node với nhau. Server này lưu trữ và phân phối public key, đồng thời cho mỗi node biết vị trí của các node khác. Server cũng đẩy xuống các access rule mà bạn đã viết.
Sự phân tách này là toàn bộ thiết kế. Data plane là peer-to-peer và được mã hóa giữa các node. Control plane là một service do Tailscale vận hành cho bạn. Mọi câu hỏi quan trọng về Tailscale, bao gồm cả những câu hỏi khó chịu về trust, đều bắt nguồn từ 2 sự thật này. Nếu bạn đã tự dựng một WireGuard VPN trên VPS, thì Tailscale chính là tunnel đó, nhưng việc phân phối key và vượt firewall đã được thực hiện thay cho bạn.
Tailscale hoạt động như thế nào?
Mạng riêng gồm các node của bạn được gọi là tailnet. Khi một máy tham gia tailnet, 4 việc xảy ra.
- Daemon
tailscaledkhởi động, tạo một cặp key WireGuard và lưu trạng thái tại/var/lib/tailscale/tailscaled.state. Private key vẫn nằm trên máy đó. Tailscale mô tả rất rõ: “private key không bao giờ rời khỏi node.” - Node đăng nhập vào coordination server và tải lên public key, cùng các địa chỉ mà node cho rằng có thể dùng để kết nối đến nó. Tailscale gọi server này là “một hộp thư dùng chung cho public key.”
- Coordination server gửi lại network map: public key, địa chỉ tailnet, tên máy và các endpoint có thể dùng của mọi node mà node này được phép kết nối.
- Sau đó, từng cặp node cố gắng thiết lập một tunnel WireGuard trực tiếp giữa chúng. Nếu thất bại, chúng chuyển packet qua relay.
Mỗi node nhận một địa chỉ cố định trong 100.64.0.0/10, dải carrier-grade NAT từ 100.64.0.0 đến 100.127.255.255. Tailscale dùng dải này vì nó được dành cho hạ tầng của nhà cung cấp, nên hiếm khi xung đột với các địa chỉ private mà server của bạn đang dùng. Trên Linux, tunnel xuất hiện dưới dạng interface có tên tailscale0.
Phần triển khai WireGuard nằm bên trong tailscaled ở userspace, không nằm trong kernel module. Vì vậy Tailscale vẫn khởi động được trong môi trường container virtualization, nơi sudo modprobe wireguard thất bại với Operation not supported. Điều này cũng có nghĩa là throughput tối đa trên một máy cụ thể thấp hơn WireGuard trong kernel. Đây là một trong các đánh đổi được trình bày trong Tailscale so với WireGuard thuần túy.
Hai command cho biết trạng thái kết nối.
tailscale ip -4
tailscale statustailscale status in một dòng cho mỗi node. Cột cuối cùng là cột cần chú ý.
100.101.102.103 web-1 you@ linux -
100.101.102.104 db-1 you@ linux active; direct 198.51.100.24:41641
100.101.102.105 ci-runner you@ linux active; relay "fra"direct kèm theo một địa chỉ và port có nghĩa là 2 máy đã tìm được đường kết nối trực tiếp với nhau, và traffic đi peer-to-peer. relay "fra" có nghĩa là traffic đang đi qua một Tailscale relay tại Frankfurt. - có nghĩa là hiện không có session đang hoạt động với node đó. Đây là trạng thái bình thường.
Máy chủ điều phối có thể và không thể xem gì
Máy chủ điều phối lưu public key và metadata. Nó biết tên máy, user hoặc tag nào sở hữu từng node, địa chỉ tailnet của từng node, các địa chỉ public mà node có thể truy cập được, thời điểm mỗi node online gần nhất và file policy bạn đã viết. Đây là bản đồ đầy đủ của toàn bộ fleet.
Máy chủ này không giữ private key, nên không thể giải mã traffic giữa hai node. Việc mã hóa diễn ra end-to-end giữa các WireGuard peer, còn máy chủ điều phối không phải là peer.
Việc máy chủ này có thể làm là phân phát key. Dù là máy chủ điều phối do bên khác host hay do bạn tự host, nó đều được tin cậy để cho các node biết public key nào thuộc tailnet. Đây là điểm then chốt trong threat model được trình bày bên dưới và là lý do tồn tại của Headscale, máy chủ điều phối mã nguồn mở do bạn tự host.
Cách 2 server phía sau các firewall khác nhau kết nối trực tiếp
NAT (network address translation) cho phép nhiều máy dùng chung một địa chỉ public. VPS của bạn thường có địa chỉ public riêng, nhưng các máy khác mà bạn muốn đưa vào tailnet thường không có: server ở nhà, build runner trong mạng văn phòng hoặc một máy nằm sau firewall của nhà cung cấp mà bạn không thể chỉnh sửa.
Tailscale tìm đường truyền bằng các kỹ thuật dựa trên STUN (session traversal utilities for NAT) và các tiêu chuẩn ICE. Mỗi node gửi một gói UDP nhỏ đến STUN server và biết được địa chỉ công khai cùng port mà router đã gán cho socket đó. Hai node báo các candidate này cho coordination server, rồi server chuyển chúng cho phía còn lại. Sau đó, cả hai node bắt đầu gửi packet cho nhau cùng lúc. Mỗi router thấy packet outbound trước, nên tạo mapping và chấp nhận reply đến từ chính địa chỉ đó. Không bên nào cần rule inbound trên firewall. Đây cũng là lý do NAS hoặc Pi ở nhà vẫn có thể được truy cập mà không cần port forwarding trên router, và dùng Tailscale thay cho port forwarding trình bày từng bước thiết lập này, bao gồm cả những việc Tailscale không thể thực hiện.
Các port được chỉ định cụ thể. Tunnel WireGuard trực tiếp dùng UDP với source port mặc định là 41641. STUN chạy qua UDP 3478 đến relay server của Tailscale. Control connection ưu tiên HTTP thuần trên TCP 80, được bọc trong encrypted transport riêng của Tailscale, và chuyển sang HTTPS trên TCP 443 khi port 80 không phản hồi. Data được relay qua DERP server của Tailscale dùng HTTPS trên TCP 443, còn peer relay chạy bên trong tailnet của bạn truyền data qua UDP. Hầu hết thời gian, bạn không cần mở inbound port nào. Tuy nhiên, trên mạng có NAT khó kết nối, cho phép UDP 41641 inbound sẽ tăng khả năng tạo được kết nối trực tiếp.
tailscale netcheckĐọc 2 dòng trong report đó. UDP: true nghĩa là máy này có thể gửi UDP ra Internet, còn UDP: false nghĩa là máy này không thể gửi, nên mọi connection từ node này sẽ được relay. MappingVariesByDestIP: true nghĩa là router gán một public port khác nhau cho từng destination, nên không thể dùng cách dự đoán địa chỉ ở trên và các node đó thường sẽ tiếp tục được relay.
Khi Tailscale dùng relay DERP thay thế
DERP (designated encrypted relay for packets) là cơ chế dự phòng. Tailscale chạy các relay tại nhiều khu vực, có thể truy cập qua TCP 443. Node không thể tạo đường truyền trực tiếp sẽ gửi các packet WireGuard qua một relay. Ngoại lệ là tailnet có các peer relay do bạn chỉ định. Đây là các thiết bị của bạn, chuyển tiếp traffic qua UDP. Tailscale thử các relay này trước và chỉ chuyển sang DERP khi không có relay nào khả dụng. Khi đó, tailscale status hiển thị kết nối là peer-relay.
Các packet vẫn được mã hóa. Tailscale nêu rõ: "DERP server không bao giờ có cách giải mã traffic của bạn. Nó chỉ chuyển tiếp một cách mù quáng traffic đã được mã hóa từ node này sang node khác." Relay chỉ thấy ciphertext và thấy node nào đang kết nối với node nào.
Relay cũng chuyển tiếp các packet đầu tiên của hầu hết kết nối. Việc tìm đường truyền trực tiếp cần một khoảng thời gian, nên session thường bắt đầu qua relay rồi được nâng cấp ngay khi hai node tìm thấy nhau. Bạn có thể theo dõi quá trình này.
tailscale ping db-1Các phản hồi đầu tiên hiển thị via DERP(fra), sau đó một dòng khác báo trạng thái tương tự via 198.51.100.24:41641. Thay đổi này là lúc tunnel được nâng cấp thành đường truyền trực tiếp. Nếu trạng thái không bao giờ thay đổi, hãy chạy tailscale netcheck ở cả hai đầu. Đường truyền qua relay vẫn hoạt động. Tuy nhiên, nó làm tăng latency vì mỗi packet phải đi vòng qua một máy thứ ba. Nếu vấn đề bạn thấy là tốc độ truyền chậm chứ không phải kết nối bị hỏng, vì sao kết nối Tailscale qua relay chậm hơn nhiều so với kết nối trực tiếp sẽ đo mức chênh lệch và hướng dẫn cách đưa VPS vào đường truyền trực tiếp.
Thêm VPS vào tailnet
Install script hỗ trợ Ubuntu và Debian.
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale upsudo tailscale up in ra một URL. Mở URL đó, xác thực, rồi node sẽ xuất hiện trong admin console. Sau đó xác nhận daemon khởi động lại sau reboot, vì đây là bước mọi người thường bỏ qua.
sudo systemctl is-enabled tailscaled
tailscale statusis-enabled phải in ra enabled, còn tailscale status phải liệt kê node mới cùng địa chỉ 100.x của node đó. Với server được tạo bằng script, URL tương tác không có tác dụng. Hãy tạo auth key trong admin console rồi truyền key đó cùng một tag để ghi nhận loại máy này.
sudo tailscale up --auth-key=tskey-auth-REPLACE-ME --advertise-tags=tag:serverNode có tag thuộc về tag thay vì người đã chạy command, nên node vẫn hoạt động sau khi tài khoản của người đó bị xóa. Trước tiên phải khai báo tag trong policy file tại tagOwners, nếu không command sẽ bị từ chối. Việc gắn tag cũng thay đổi cách máy được tính vào plan của bạn, vì resource có tag được tính phí riêng với các device của cá nhân, và phần thực sự bao gồm những gì trong free tier nêu rõ các giới hạn đó.
Có 2 thiết lập quan trọng khi quản lý nhiều node. Mặc định, node key hết hạn sau 180 ngày (tính đến tháng 10 năm 2026), và khi key hết hạn thì “các kết nối đến/từ endpoint đó sẽ ngừng hoạt động” cho đến khi device xác thực lại. Admin có thể chọn Temporarily extend key trên máy đã hết hạn trong admin console. Tùy chọn này cho bạn 30 phút để đăng nhập lại hoặc tắt thời hạn hết hạn. Node được xác thực bằng tag, như node ở trên, mặc định đã tắt thời hạn hết hạn của key. Với mọi server unattended khác, hãy mở dòng của máy trong admin console rồi chọn Disable Key Expiry. MagicDNS, được bật mặc định cho các tailnet tạo từ ngày 20 tháng 10 năm 2022 trở đi, cấp cho mỗi node một tên như db-1.yak-bebop.ts.net. Tên này được phân giải bởi stub resolver tại 100.100.100.100. Hãy dùng tên thay vì địa chỉ, vì node được dựng lại sẽ nhận địa chỉ mới nhưng vẫn giữ tên cũ.
Nếu quá trình install thất bại ở apt hoặc repository, phần các lỗi install Tailscale thường gặp trên Ubuntu trình bày cách khắc phục.
Truy cập service bind vào localhost
Đây là lúc tailnet phát huy tác dụng, đồng thời cũng là chỗ nhiều người bị vướng. Tham gia tailnet không khiến service loopback có thể truy cập được.
ss -tlnp | grep 3000Nếu lệnh này in ra 127.0.0.1:3000, socket chỉ chấp nhận các packet có địa chỉ đích là 127.0.0.1. Request từ node khác đến với địa chỉ đích là địa chỉ 100.x của node này, nên kernel không có listener nào nhận request đó và trả về TCP reset. Client báo Connection refused. Tunnel vẫn hoạt động bình thường. Vấn đề nằm ở listener.
Có 2 cách xử lý đúng. Bind service vào địa chỉ tailnet của node. Cách này giữ service ngoài public interface và không cần proxy: truyền --bind 100.101.102.104 hoặc dùng tùy chọn tương đương trong config; với container, publish port dưới dạng -p 100.101.102.104:3000:3000. Hoặc giữ service trên loopback và đặt Tailscale phía trước service đó.
tailscale serve 3000Cách này proxy các request đến http://127.0.0.1:3000 và cung cấp service trong tailnet với tên ts.net qua HTTPS, sau khi bật HTTPS certificate cho tailnet. Service vẫn chỉ private đối với các node của bạn. Phiên bản public của cùng mô hình này là Funnel. Tailscale serve với funnel giải thích nên dùng tùy chọn nào.
2 tác vụ liên quan có trang riêng. Để truy cập toàn bộ private network chưa cài Tailscale, hãy dùng subnet router trên VPS. Để chuyển outbound internet traffic của một node qua node khác, hãy dùng exit node.
Đóng các port không còn cần thiết
Khi mọi administrator đều truy cập được vào máy qua tailnet, public port 22 không còn cần thiết. Đây là lợi ích thực tế: port đã đóng thì không thể bị brute force, và log không còn đầy các lần thử truy cập.
Thứ tự thực hiện rất quan trọng. Trước tiên, thêm quyền truy cập qua tailnet. Xác nhận bạn có thể đăng nhập qua kết nối này từ một session thứ hai. Chỉ sau đó mới xóa rule public.
sudo ufw allow in on tailscale0
sudo ufw status verboseSau đó, xóa rule SSH public và kết nối lại bằng tên MagicDNS. Lưu ý ufw allow in on tailscale0 thực sự làm gì: nó tin cậy mọi lưu lượng đi vào qua tunnel, vì vậy file policy của Tailscale sẽ trở thành cơ chế kiểm soát truy cập thay cho ufw. Hãy viết policy dựa trên điều đó.
Một cảnh báo dành cho những ai chạy container. Port được publish bởi Docker sẽ tự cài các NAT rule và bypass ufw, nên ufw deny không đóng được port đó. Docker publish port bypass ufw giải thích cơ chế này. Publish port vào địa chỉ tailnet như trên sẽ tránh được vấn đề đó. Nếu app chạy bằng Docker Compose, Tailscale sidecar trong stack Compose còn xử lý triệt để hơn bằng cách xóa hoàn toàn port đã publish, để container chỉ có thể được truy cập qua tên tailnet.
Tailscale bảo vệ gì và không bảo vệ gì
Cần nói rõ điều này, vì cách marketing thường làm mờ ranh giới.
Được bảo vệ: lưu lượng giữa hai node được mã hóa end-to-end bằng WireGuard, và không relay nào ở giữa có thể đọc được. Private key không bao giờ rời khỏi máy đã tạo ra chúng. Node không cần public port inbound, nên Internet không có gì trên cổng 22 hoặc 5432 để scan. Quyền truy cập giữa các node được quyết định bằng policy file, không phải bởi bất kỳ ai biết một địa chỉ.
Không được bảo vệ: coordination server nhìn thấy device graph của bạn. Metadata này vốn đã nhạy cảm, vì tên máy, chủ sở hữu, địa chỉ và thời gian online mô tả hạ tầng của bạn. Server cũng phân phối key, và đây là rủi ro nghiêm trọng hơn. Tailscale nói thẳng: "Nếu Tailscale có hành vi độc hại và âm thầm chèn các node mới vào network của bạn, Tailscale có thể gửi hoặc nhận lưu lượng đến các node hiện có dưới dạng plaintext." Nhà cung cấp single sign-on của bạn nằm trong cùng trust path, vì bất kỳ ai có thể mint identity ở đó đều có thể thêm một node. Một node bị breach cũng là một peer bên trong tailnet, nên nó có thể truy cập tiếp đến đâu là tùy policy của bạn cho phép. Rủi ro này có chấp nhận được hay không phụ thuộc vào đối tượng bạn đang phòng vệ, và mô hình trust đầy đủ phân tích từng trường hợp, bao gồm những gì một identity account bị đánh cắp thực sự có thể làm.
Có hai cách xử lý rủi ro phân phối key. Cách thứ nhất là tailnet lock, yêu cầu các node trusted hiện có ký bằng cryptographic signature cho node mới trước khi các node khác chấp nhận node đó. Control plane thêm một node không có signature hợp lệ sẽ bị bỏ qua. Admin console tạo chính xác dòng tailscale lock init cho các node dùng để ký, và mọi node đều có thể xác nhận thông tin mình nhận được.
tailscale lock statusTất cả node phải báo cáo cùng một tập trusted signing key. Cách thứ hai là tự chạy control plane. Headscale coordination server tự host dùng cùng protocol với cùng các client, qua đó chuyển device graph và việc phân phối key sang hardware do bạn sở hữu. Khi đó, bạn cũng chịu trách nhiệm về uptime của server này. Nếu bạn vẫn đang so sánh các control plane tự host thay vì chọn giải pháp này, NetBird là một mesh VPN riêng, với server được bạn tự chạy end-to-end trên một VPS.
Có một thiết lập mặc định cần sửa ngay trong ngày đầu tiên. Tailnet mới được phát hành với quyền permissive: "policy file mặc định của tailnet cho phép mọi device trong tailnet giao tiếp với nhau." Ngay khi bạn thêm một section acls, mô hình chuyển sang deny by default và chỉ các rule của bạn mới được phép đi qua.
{
"tagOwners": {
"tag:server": ["autogroup:admin"]
},
"acls": [
{"action": "accept", "src": ["autogroup:member"], "dst": ["tag:server:22"]}
]
}Chính sách đó cho phép các thành viên trong tailnet truy cập SSH trên những server được gắn tag và không truy cập gì khác. Hãy thêm một rule cho từng service thay vì giữ wildcard, vì wildcard cho phép một key trên laptop bị đánh cắp truy cập vào database của bạn. Nếu bạn vẫn đang chọn một mesh VPN, cách viết các rule như vậy là một trong những điểm mà các lựa chọn thực sự khác nhau, và NetBird so với Tailscale so sánh hai mô hình policy cùng với bên vận hành control plane.
Các dạng lỗi và chuỗi bạn sẽ thấy
tailscale status luôn trả về relay. Hai node không thiết lập được đường truyền trực tiếp. Chạy tailscale netcheck ở cả hai đầu. UDP: false nghĩa là UDP bị chặn trên chiều outbound, nên chỉ relay mới hoạt động được. MappingVariesByDestIP: true nghĩa là đang có NAT dạng hard NAT, và cho phép UDP 41641 inbound ở phía bạn kiểm soát thường sẽ khắc phục được lỗi này.
Một node đã hoạt động nhiều tháng nhưng biến mất. Nguyên nhân thường gặp là node key hết hạn sau thời hạn mặc định 180 ngày, vì vậy trước tiên hãy kiểm tra máy đó trong admin console. Nếu trạng thái hiển thị là đã hết hạn, sudo tailscale up trên máy sẽ khôi phục node, còn tắt key expiry trên server sẽ ngăn lỗi lặp lại. Nếu key chưa hết hạn, hãy kiểm tra policy file, vì hướng dẫn chính thức của Tailscale cho thiết bị không xuất hiện trong tailscale status là kiểm tra các access rule đang ngăn kết nối.
Các peer vẫn được liệt kê nhưng kết nối bị timeout. Nếu tailscale ping nhận được phản hồi, kết nối mạng đang hoạt động và nguyên nhân có khả năng là policy đang từ chối lưu lượng. Kiểm tra section acls để tìm rule áp dụng cho source, destination và port này. Packet bị từ chối sẽ bị drop thay vì nhận phản hồi, nên bạn gặp timeout thay vì Connection refused.
Tên MagicDNS không phân giải được. ping db-1 fail trong khi ping 100.101.102.104 hoạt động. Trước tiên hãy xác nhận client chấp nhận DNS setting của Tailscale: node được khởi động với --accept-dns=false sẽ không gửi query đến stub resolver tại 100.100.100.100. Sau đó kiểm tra cat /etc/resolv.conf và mọi thành phần khác trên máy có ghi vào file đó. Trên hệ thống dùng systemd-resolved, file này thường là symlink đến /run/systemd/resolve/stub-resolv.conf, và việc không liệt kê 100.100.100.100 trong đó là bình thường. Khi tailscaled ghi trực tiếp vào file, DHCP client hoặc công cụ khác ghi đè file này sẽ làm hỏng MagicDNS. Nếu cả hai khả năng trên đều không đúng, lỗi cũng có thể nằm trong cấu hình DNS cục bộ hoặc DNS của mạng. Đây là cùng nhóm lỗi với DNS bị hỏng bên trong tunnel WireGuard.
tailscale up từ chối tag của bạn. Tag chưa được khai báo bên dưới tagOwners trong policy file. Thêm tag vào đó rồi chạy lại command.
FAQ
Tailscale là VPN hay mesh network?
Cả hai từ đều chính xác và mô tả các lớp khác nhau. Tunnel dùng WireGuard, nên đây là một VPN. Topology là mesh, vì mỗi node tạo tunnel trực tiếp đến từng node mà nó giao tiếp, thay vì gửi mọi packet qua một server trung tâm. Coordination server nằm trong control path, không nằm trong data path. Vì vậy, nếu coordination server không thể truy cập, các tunnel hiện có vẫn tiếp tục truyền traffic. Khi xảy ra sự cố, việc node mới tham gia và việc áp dụng thay đổi về key hoặc policy sẽ bị dừng. Tuy nhiên, đây không mặc định là VPN bảo mật quyền riêng tư: website vẫn thấy public address của bạn cho đến khi bạn gửi traffic qua một exit node, và Tailscale ẩn gì với website và ISP của bạn tùy theo từng cấu hình.
Tailscale có đọc được traffic của tôi không?
Không đọc được nội dung. Traffic được mã hóa end-to-end giữa các node bằng WireGuard, private key không bao giờ rời khỏi node, còn relay DERP chỉ chuyển tiếp packet mà không có cách giải mã. Tailscale vẫn thấy metadata: tên máy, owner, public key, địa chỉ endpoint và thời điểm mỗi node online. Tailscale cũng phân phối key, nên coordination server bị compromise có thể cố chèn một node mà toàn bộ fleet của bạn sẽ tin cậy. Tailnet lock ngăn việc này bằng cách yêu cầu chữ ký từ các node đáng tin cậy của chính bạn. Headscale loại bỏ hosted control plane khỏi mô hình này.
Tôi có cần mở port trên firewall cho Tailscale không?
Hầu như không cần mở inbound. Hướng dẫn của Tailscale là “phần lớn thời gian, bạn không cần mở port firewall nào”. Về outbound, node cần TCP 443 đến coordination server và các relay, cùng với UDP 3478 cho STUN. Tunnel trực tiếp dùng UDP với source port mặc định là 41641. Cho phép UDP 41641 inbound là tùy chọn. Việc này chỉ giúp các kết nối trực tiếp thiết lập thành công trên những network khó kết nối.
Vì sao các node khác không truy cập được service của tôi trên port 3000?
Trước tiên, kiểm tra bind address bằng ss -tlnp. Listener trên 127.0.0.1:3000 sẽ từ chối các kết nối gửi đến địa chỉ tailnet 100.x của node, vì socket đó chỉ chấp nhận destination loopback. Client sẽ thấy Connection refused. Hãy bind service vào địa chỉ tailnet hoặc chạy tailscale serve 3000 để proxy cho service. Nếu listener đã chạy trên 0.0.0.0 nhưng connection bị timeout thay vì bị từ chối, bind address không phải nguyên nhân. Trước tiên, kiểm tra policy rule và host firewall. Sau đó kiểm tra network firewall và xem authentication của một trong hai thiết bị có hết hạn hay chưa.
Tôi có nên chạy Headscale thay cho coordination server của Tailscale không?
Hãy dùng Headscale khi device graph hoặc việc phân phối key phải nằm trên infrastructure do bạn kiểm soát, hoặc khi tailnet phải hoạt động mà không phụ thuộc vào dịch vụ bên ngoài. Client và protocol vẫn giống nhau. Đổi lại, bạn phải tự vận hành coordination server. Nếu server này outage, node mới không thể tham gia và các thay đổi policy không được áp dụng. Với fleet nhỏ, hosted control plane bật tailnet lock thường là lựa chọn cân bằng hơn.