selinux簡介

来源:https://www.cnblogs.com/xiaoshiwang/archive/2020/03/01/12387549.html
-Advertisement-
Play Games

selinux概念 由美國國家安全局(NSA)和SCC聯合開發的,強制訪問控制的安全模塊。2000年以GPL開源,linux2.6內核後集成在內核里。 不啟用selinux時,訪問模式叫:DAC(discretionary access control)自由訪問控制 在DAC模式下的進程能夠訪問哪些 ...


selinux概念

由美國國家安全局(NSA)和SCC聯合開發的,強制訪問控制的安全模塊。2000年以GPL開源,linux2.6內核後集成在內核里。

不啟用selinux時,訪問模式叫:DAC(discretionary access control)自由訪問控制

在DAC模式下的進程能夠訪問哪些資源是由啟用這個進程的用戶身份決定的,這個用戶能訪問的,這個進程都可以訪問。

啟用selinux時,訪問模式叫:MAC(Mandatory access control)強制訪問控制

在MAC模式下的進程能夠訪問哪些資源是由selinux設定的。

selinux的工作類型

selinux的工作類型定義在/etc/selinux/config文件中

centos7:

# cat /etc/selinux/config

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

centos6:

# cat /etc/selinux/config

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected,
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted
  • targeted:保護常見的網路服務(預設工作類型)
  • minimum:只對選擇的服務保護

selinux安全上下文

  • 傳統linux,一切皆文件,由用戶,組,許可權控制訪問

  • 在selinux中,一切皆對象(object),由存放在inode的擴展屬性域的安全元素所訪問控制。

    查看inode的擴展屬性域的命令:ls -Zps -Z

    這些屬性起名叫標簽或context。

    ls:

    # ls -lZ
    -rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
    -rw-r--r--. root root system_u:object_r:admin_home_t:s0 initial-setup-ks.cfg
    -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 linux-3.10.67.tar.xz
    drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 scripts

    ps:

    # ps auxZ
    LABEL                           USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    system_u:system_r:init_t:s0     root         1  0.0  0.1 193788  6904 ?        Ss   05:25   0:06 /usr/lib/systemd/systemd --swit
    system_u:system_r:kernel_t:s0   root         2  0.0  0.0      0     0 ?        S    05:25   0:00 [kthreadd]
    system_u:system_r:kernel_t:s0   root         3  0.0  0.0      0     0 ?        S    05:25   0:00 [ksoftirqd/0]
  • 所以文件,埠,進程都具備安全標簽:安全上下文(security context)

  • 安全上下位由5個元素組成:user:role:type:sensitivity:category

    • user:登錄系統的用戶類型
      • root:root用戶
      • user_u:普通用戶
      • system_u:系統用戶
      • unconfined_t:自由進程/文件。多數本地進程都屬於此。
    • role:定位文件,進程和用戶的用途。文件:object_r;進程和用戶:system_r
    • type:數據類型。最常用的屬性,target策略就是根據type的值,控制可以訪問/不可訪問哪些資源。但是有個問題,每個資源只有唯一的type,當有多個別的東西想訪問同一個資源的時候就麻煩了,就要修改type成public_content_t(只讀,不可以修改這個資源);public_content_rw_t(讀寫)
    • sensitivity:預設是s0
    • category:target工作類型下,不使用。
  • 標簽/context分實際的標簽和期望標簽

    • 實際標簽:使用ls -Z和ps -Z看到的標簽。

    • 期望標簽:安裝操作系統後,系統給的標簽。標簽是可以修改的,所以有期望標簽,修改了某個文件的標簽後,這個文件的期望標簽和實際標簽就不一樣了。

      查看文件,進程,埠的期望標簽:semanage fcontext -l

      # semanage fcontext -l | grep "/var/log/messages"
      /var/log/messages[^/]*                             all files          system_u:object_r:var_log_t:s0
      # ls -Z /var/log/messages
      -rw-------. root root system_u:object_r:var_log_t:s0   /var/log/messages

      期望標簽存放在:/etc/selinux/targeted/contexts/files/目錄

      # ls /etc/selinux/targeted/contexts/files/
      file_contexts           file_contexts.homedirs.bin  file_contexts.subs
      file_contexts.bin       file_contexts.local         file_contexts.subs_dist
      file_contexts.homedirs  file_contexts.local.bin     media

selinux策略

  • object:所以可以讀取的對象,包括文件,目錄,進程,埠
  • subject:進程
  • 當一個subject要訪問object時,selinux執行AVC(access vector cache)檢查,在AVC中,subject和object的許可權被緩存。
  • 安全策略:定義subject讀取object的規則資料庫,規則中記錄了哪個類型的(type)的subject使用哪個方法讀取哪一個object是允許的還是拒絕的,並且定義了哪種行為是允許或拒絕的。

啟用selinux

查看selinux是啟用還是禁用

# getenforce
Enforcing
[root@localhost ~]# cat /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

enforcing:啟用狀態

permissive:沒啟用,但是違反了selinux的規則,只出警告信息而已。

disabled:禁用狀態。

  • 臨時啟用:

    # setenforce 1
    # getenforce
    Enforcing
  • 臨時禁用:

    # setenforce 0
    # getenforce
    Permissive

    註意:使用命令setenforce,只能在Enforcing和Permissive間切換。不能從disabled狀態切換成Enforcing。

永久修改selinux啟用或禁用:修改文件/etc/selinux/config,重啟才生效。

禁用後(disabled而不是permissive)創建的文件就沒有標簽了,

而且【-rw-r--r--】後面沒有點,有點就說明有標簽。

# sestatus
SELinux status:                 disabled
# setenforce 1
setenforce: SELinux is disabled
# touch temp2
[root@localhost ~]# ls -Z temp2
-rw-r--r-- root root ?                                temp2

從disabled切換到enabled後,在看剛纔創建的temp2文件:

有點了,但是type是unlabeled_t

# getenforce
Enforcing
# ls -Z temp2
-rw-r--r--. root root system_u:object_r:unlabeled_t:s0 temp2

查看詳細狀態信息:

# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   permissive//當前是禁用的
Mode from config file:          enforcing//配置文件是啟用的
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      31

定義的策略存放在:SELinuxfs mount /sys/fs/selinux

avc緩存在avc目錄。

# ls /sys/fs/selinux/
access    checkreqprot          context       disable           load    null                 policyvers      status
avc       class                 create        enforce           member  policy               reject_unknown  user
booleans  commit_pending_bools  deny_unknown  initial_contexts  mls     policy_capabilities  relabel

安全布爾值存放在:/sys/fs/selinux/booleans

# pwd
/sys/fs/selinux/booleans
[root@localhost booleans]# ll ftp*
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_anon_write
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_connect_all_unreserved
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_connect_db
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_full_access
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_use_cifs
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_use_fusefs
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_use_nfs
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_use_passive_mode

文件ftpd_anon_write里的內容是2個0。從文件名字可以看出來是ftp的匿名寫,值是0,說明不允許匿名寫。

# cat ftpd_anon_write
0 0

管理文件安全標簽

1,修改標簽中的type:chcon-t file

測試標簽中type的作用,/var/log/messages文件的標簽中的type是var_log_t。

手動使用logger命令,往它裡面寫東西,發現是可以寫進去的。

修改它的type成tmp_t,再用logger寫,發現寫不進去了。

# ll /var/log/messages -Z
-rw-------. root root system_u:object_r:var_log_t:s0   /var/log/messages
# logger "test  sdf "
# tail -1 /var/log/messages
Feb 29 18:33:32 localhost root: test  sdf
# chcon -t tmp_t /var/log/messages
# ll -Z /var/log/messages
-rw-------. root root system_u:object_r:tmp_t:s0       /var/log/messages
# logger "test  2222sdf "
# grep "test  2222sdf " /var/log/messages

根據某個文件的標簽,修改:chcon --reference f1 f2

把文件f2的標簽修改成和文件f1完全一樣。

# ll -Z /tmp/website/
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 aa
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html
# chcon --reference /tmp/website/index.html /tmp/website/aa
# ll -Z /tmp/website/
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 aa
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html

選項-R:遞歸修改目錄所有的文件

# ls /tmp/website/d1
11  22
# ll /tmp/website/d1/11 -Z
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /tmp/website/d1/11
# ll /tmp/website/d1/22 -Z
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /tmp/website/d1/22
# ll /tmp/website/d1/ -Zd
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 /tmp/website/d1/
# chcon -R --reference /var/www/html/ /tmp/website/d1/
# ll /tmp/website/d1/ -Zd
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /tmp/website/d1/
# ll /tmp/website/d1/ -Z
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 11
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 22

2,cp命令和mv命令多標簽的影響。

cp命令type會改變。

# ll -Z /var/log/messages
-rw-------. root root system_u:object_r:var_log_t:s0   /var/log/messages
# cp /var/log/messages /root/
# ll -Z messages
-rw-------. root root unconfined_u:object_r:admin_home_t:s0 messages

mv命令不改變type

# mv messages /tmp/
# ll /tmp/messages  -Z
-rw-------. root root unconfined_u:object_r:admin_home_t:s0 /tmp/messages

3,修改回原來的type,但是忘了原來的type是啥了怎麼辦,去看期望(原始)策略是啥。

# semanage fcontext -l | grep "/var/log/message"
/var/log/messages[^/]*       all files       system_u:object_r:var_log_t:s0

還有一種更簡單的方法:restorecon

# chcon -t tmp_t /var/log/messages
# ll -Z /var/log/messages
-rw-------. root root system_u:object_r:tmp_t:s0       /var/log/messages
# restorecon /var/log/messages
# ll -Z /var/log/messages
-rw-------. root root system_u:object_r:var_log_t:s0   /var/log/messages

把/var/log/messages回覆成原來的標簽後,有可能還log還是寫不進去,這時就要重啟服務了。systemctl rsyslog restart

4,修改httpd的預設根目錄,導致selinux標簽不對,網頁文件無法訪問。

  • 修改httpd的配置文件/etc/httpd/conf/httpd.conf,把服務的目錄修改成/tmp/website/

    # ll -Z /tmp/website/ -d
    drwxr-xr-x. root root unconfined_u:object_r:user_tmp_t:s0 /tmp/website/

    type是user_tmp_t

  • 在/tmp/website/建立index.html文件

    # ll -Z /tmp/website/
    -rw-r--r--. root root unconfined_u:object_r:user_tmp_t:s0 index.html

    type是user_tmp_t

  • 啟動httpd

  • 在瀏覽器訪問index.html

  • 結果是訪問不到

原因:/tmp/website/index.html的標簽的type不符合selinux對httpd的要求,所以httpd進程無法訪問它。

httpd能夠訪問的標簽是:httpd_sys_content_t。

而/tmp/website/index.html文件的type是user_tmp_t,所以httpd不可以訪問它,被selinux給擋住了。

# ll -Zd /var/www/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/

解決辦法:

1,安裝桌面小程式,能夠把selinux相關的信息顯示出來。(不安裝也無所謂)

2,添加/tmp/website/目錄的期望(預設)策略,到selinux。

添加選項:-a

指明type:-t

/tmp/website(/.*)?:正則表達式/tmp/website目錄自身和目錄下的所有文件的意思。

# semanage fcontext -a -t httpd_sys_content_t "/tmp/website(/.*)?"
# semanage fcontext -l | grep "/tmp/website"
tmp/website(/.*)?                                  all files          system_u:object_r:httpd_sys_content_t:s0

3,由於/tmp/website/有了期望策略,所以恢復/tmp/website/的標簽成,預設標簽。

選項-R:遞歸修改目錄下的所有文件。

# restorecon -R /tmp/website/
# ll -Zd /tmp/website/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /tmp/website/
# ll -Z /tmp/website/
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html

4,重啟httpd

5,當不想讓/tmp/website/是httpd的根目錄了,刪除它在selinux里的期望策略

刪除選項:-d

# semanage fcontext -d -t httpd_sys_content_t "/tmp/website(/.*)?"

管理埠標簽

1,查看埠期望(預設)策略:

http協議的埠的期望(預設)策略:80, 81, 443, 488, 8008, 8009, 8443, 9000是可以使用的。

所以不能把其他的埠用於http服務。

# semanage port -l
SELinux Port Type              Proto    Port Number

afs3_callback_port_t           tcp      7001
afs3_callback_port_t           udp      7001
# semanage port -l | grep http
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000

2,添加埠到預設策略

選項-a:添加

選項-t:指定type

選項-p:指定傳輸層的協議(tcp或udp)類型

# semanage port -a -t http_port_t -p tcp 9932
[root@localhost ~]# semanage port -l | grep "^http_port_t"
http_port_t          tcp      9932, 80, 81, 443, 488, 8008, 8009, 8443, 9000

3,從預設策略里刪除埠

# semanage port -d -t http_port_t -p tcp 9932
# semanage port -l | grep "^http_port_t"
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000

4,把埠策略里的某個埠,移動到另一個策略

讓9000埠也能用於ssh服務。

# semanage port -l | grep "^http_port_t"
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
# semanage port -m -t ssh_port_t -p tcp 9000
# semanage port -l | grep "^ssh_port_t"
ssh_port_t                     tcp      9000, 22
# semanage port -l | grep "^http_port_t"
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443

管理selinux布爾值開關

布爾值的作用:細化控制某個服務里的某個小功能是否可以使用。

1,查看布爾值

State:是當前的狀態(記憶體中的)

Default:是預設值(本地磁碟存儲的)

# semanage boolean -l
SELinux boolean                State  Default Description

privoxy_connect_any            (on   ,   on)  Allow privoxy to connect any
smartmon_3ware                 (off  ,  off)  Allow smartmon to 3ware

比如:

httpd_enable_cgi:控制httpd的cgi功能是否可用。

httpd_enable_homedirs:控制httpd是否可以訪問家目錄。

# semanage boolean -l | grep httpd_enable
httpd_enable_cgi               (on   ,   on)  Allow httpd to enable cgi
httpd_enable_homedirs          (off  ,  off)  Allow httpd to enable homedirs

另一種命令:getsebool

選項-a:查看全部布爾值

# getsebool -a | grep httpd_use
httpd_use_cifs --> off
httpd_use_fusefs --> off

2,修改布爾值:setsebool

只修改當前狀態(重啟後,恢覆成default):

# setsebool httpd_enable_homedirs=on
# semanage boolean -l | grep httpd_enable
httpd_enable_cgi               (on   ,   on)  Allow httpd to enable cgi
httpd_enable_homedirs          (on   ,  off)  Allow httpd to enable homedirs
httpd_enable_ftp_server        (off  ,  off)  Allow httpd to enable ftp server

既修改當前狀態,也修改default狀態:

# semanage boolean -l | grep httpd_enable
httpd_enable_homedirs          (off  ,  off)  Allow httpd to enable homedirs
# setsebool -P httpd_enable_homedirs=on
# semanage boolean -l | grep httpd_enable
httpd_enable_homedirs          (on   ,   on)  Allow httpd to enable homedirs

3,查看都修改過哪些布爾值

# semanage boolean -l -C
SELinux boolean                State  Default Description

httpd_enable_homedirs          (on   ,   on)  Allow httpd to enable homedirs

管理日誌

日誌工具: yum install -y setroubleshoot。有圖形界面。

使用下麵命令啟動圖形界面:

# sealert

1,查看由selinux的限制導致的服務不好用的日誌,日誌文件:/var/log/message

由selinux的限制導致的服務不好用的日誌的特點是有:setroubleshoot字樣,並告訴使用sealert命令去查看詳細的日誌。選項-l後面的串是這條日誌的標識。

Mar  1 00:04:05 localhost python: SELinux is preventing in 。。。。。。。。
sealert -l 0d882054-5ff7-4693-bf09-7b02f763df6c

使用sealert查看:

# sealert -l 0d882054-5ff7-4693-bf09-7b02f763df6c

使用sealert輸出的日誌是保存在文件: /var/log/audit/audit.log

2,整理/var/log/audit/audit.log文件,輸出可讀的格式

# sealert -a /var/log/audit/audit.log

查看selinux幫助

安裝selinux幫助文檔:

# yum install selinux-policy-doc

查看與selinux相關的幫助文檔有哪些:

# man -k _selinux

如果沒有顯示出來,說明沒有更新man的資料庫,使用下麵的命令更新:

  • centos6:makewhatis
  • centos7:mandb

查看與ftp相關的selinux幫助:

# man 8 ftpd_selinux

c/c++ 學習互助QQ群:877684253

本人微信:xiaoshitou5854


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • A finally block does not always xecute. The code in the try block could go into an infinite loop, the exception could rigger a “fail fast” (which take ...
  • 項目需要(或者前後端分離的需要),前端我使用了用戶控制項庫,由後端用代碼載入和控制。 然而用戶控制項庫沒法指定資源字典,於是在用戶控制項的xaml文件裡面手工添加了資源字典 設計階段方便了,生成dll,被主程式調用的時候,就報錯了,說沒有該資源文件(d1.xaml),研究Pack Url後明白,可以有兩種 ...
  • C#中實現文件拖放打開的方法 設置Form屬性 AllowDrop = True; 在Form事件中 private void Form1_DragDrop(object sender, DragEventArgs e) { string localFilePath = ((System.Array ...
  • 修改註冊表,雙擊文件直接打開 string strProject = "Exec"; string p_FileTypeName =".cdb";//文件尾碼 string fileName = System.Windows.Forms.Application.ExecutablePath;// 獲 ...
  • 作者: 魔法軟糖 日期: 2020-02-27 引言 ************************************* .ini 文件是Initialization File的縮寫,即配置文件 。是windows的系統配置文件所採用的存儲格式。 它具有方便易用的特點,和註冊表的鍵值有著類似 ...
  • 最近開始試著玩Unity3D,要為場景中的物體編輯腳本。Unity3D推薦的腳本語言是C#,在Unity打開C#就會使用Visual Studio來進行編輯。 啟動Visual Studio之後註意到,Unity類和方法名都沒有代碼補全,而且Unity似乎也編譯不過: 在網上找了一圈,發現並沒有人遇 ...
  • 在 C 中 Object 是所有類的基類,所有的結構和類都直接或間接的派生自它。前面這段話可以說所有的 C 開發人員都知道,但是我相信其中有一部分程式員並不清楚甚至不知道我們常用的 ToString 、 Equals 和 GetHashCode 虛方法都來自於 Object 類,並且我們可以對它們進 ...
  • 前言 今天這篇博客是接我的上一篇博客 https://www.cnblogs.com/y-yp/p/12191258.html,繼續介紹一下MMF在Linux上的用法 ps:本來本地調試完case,想放到伺服器上跑跑看,結果竟然報"PlatformNotSupportedException",然後仔 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...