PHP 安全編程建議

PHP 安全編程建議

簡介

要提供互聯網服務,當你在開發代碼的時候必須時刻保持安全意識。可能大部分 PHP 腳本都對安全問題都不在意,這很大程度上是因為有大量的無經驗程序員在使用這門語言。但是,沒有理由讓你因為對你的代碼的不確定性而導致不一致的安全策略。當你在服務器上放任何涉及到錢的東西時,就有可能會有人嘗試破解它。創建一個論壇程序或者任何形式的購物車,被攻擊的可能性就上升到了無窮大。


背景

為了確保你的 web 內容安全,這里有一些常規的安全準則:

別相信表單

攻擊表單很簡單。通過使用一個簡單的 JavaScript 技巧,你可以限制你的表單只允許在評分域中填寫 1 到 5 的數字。如果有人關閉了他們瀏覽器的 JavaScript 功能或者提交自定義的表單數據,你客戶端的驗證就失敗了。

用戶主要通過表單參數和你的腳本交互,因此他們是最大的安全風險。你應該學到什么呢?在 PHP 腳本中,總是要驗證 傳遞給任何 PHP 腳本的數據。在本文中,我們向你演示了如何分析和防范跨站腳本(XSS)攻擊,它可能會劫持用戶憑據(甚至更嚴重)。你也會看到如何防止會玷污或毀壞你數據的 MySQL 注入攻擊。

別相信用戶

假定你網站獲取的每一份數據都充滿了有害的代碼。清理每一部分,即便你相信沒有人會嘗試攻擊你的站點。

關閉全局變量

你可能會有的最大安全漏洞是啟用了 register_globals 配置參數。幸運的是,PHP 4.2 及以后版本默認關閉了這個配置。如果打開了 register_globals,你可以在你的 php.ini 文件中通過改變 register_globals 變量為 Off 關閉該功能:

register_globals = Off

新手程序員覺得注冊全局變量很方便,但他們不會意識到這個設置有多么危險。一個啟用了全局變量的服務器會自動為全局變量賦任何形式的參數。為了了解它如何工作以及為什么有危險,讓我們來看一個例子。

假設你有一個稱為 process.php 的腳本,它會向你的數據庫插入表單數據。初始的表單像下面這樣:

<input name="username" type="text" size="15" maxlength="64">

運行 process.php 的時候,啟用了注冊全局變量的 PHP 會將該參數賦值到 $username 變量。這會比通過 $_POST['username']$_GET['username'] 訪問它節省擊鍵次數。不幸的是,這也會給你留下安全問題,因為 PHP 會設置該變量的值為通過 GET 或 POST 的參數發送到腳本的任何值,如果你沒有顯示地初始化該變量并且你不希望任何人去操作它,這就會有一個大問題。

看下面的腳本,假如 $authorized 變量的值為 true,它會給用戶顯示通過驗證的數據。正常情況下,只有當用戶正確通過了這個假想的 authenticated_user() 函數驗證,$authorized 變量的值才會被設置為真。但是如果你啟用了register_globals,任何人都可以發送一個 GET 參數,例如 authorized=1 去覆蓋它:

<?php
// Define $authorized = true only if user is authenticated
if (authenticated_user()) {$authorized = true;
}
?>

這個故事的寓意是,你應該從預定義的服務器變量中獲取表單數據。所有通過 post 表單傳遞到你 web 頁面的數據都會自動保存到一個稱為 $_POST 的大數組中,所有的 GET 數據都保存在$_GET 大數組中。文件上傳信息保存在一個稱為$_FILES 的特殊數據中。另外,還有一個稱為$_REQUEST 的復合變量。

要從一個 POST 方法表單中訪問 username 字段,可以使用 $_POST['username']。如果 username 在 URL 中就使用$_GET['username']。如果你不確定值來自哪里,用$_REQUEST['username']

<?php
$post_value = $_POST['post_value'];
$get_value = $_GET['get_value'];
$some_variable = $_REQUEST['some_value']; 
?>

$_REQUEST 是 $_GET、$_POST、和 $_COOKIE 數組的結合。如果你有兩個或多個值有相同的參數名稱,注意 PHP 會使用哪個。默認的順序是 cookie、POST、然后是 GET。

推薦安全配置選項

這里有幾個會影響安全功能的 PHP 配置設置。下面是一些顯然應該用于生產服務器的:

  • register_globals 設置為 off
  • safe_mode 設置為 off
  • error_reporting 設置為 off。如果出現錯誤了,這會向用戶瀏覽器發送可見的錯誤報告信息。對于生產服務器,使用錯誤日志代替。開發服務器如果在防火墻后面就可以啟用錯誤日志。(LCTT 譯注:此處據原文邏輯和常識,應該是“開發服務器如果在防火墻后面就可以啟用錯誤報告,即 on。”)
  • 停用這些函數:system()、exec()、passthru()、shell_exec()、proc_open()、和 popen()。
  • open_basedir 為 /tmp(以便保存會話信息)目錄和 web 根目錄,以便腳本不能訪問這些選定區域外的文件。
  • expose_php 設置為 off。該功能會向 Apache 頭添加包含版本號的 PHP 簽名。
  • allow_url_fopen 設置為 off。如果你能夠注意你代碼中訪問文件的方式-也就是你驗證所有輸入參數,這并不嚴格需要。
  • allow_url_include 設置為 off。對于任何人來說,實在沒有明智的理由會想要訪問通過 HTTP 包含的文件。

一般來說,如果你發現想要使用這些功能的代碼,你就不應該相信它。尤其要小心會使用類似 system() 函數的代碼-它幾乎肯定有缺陷。

啟用了這些設置后,讓我們來看看一些特定的攻擊以及能幫助你保護你服務器的方法。

SQL 注入攻擊

由于 PHP 傳遞到 MySQL 數據庫的查詢語句是用強大的 SQL 編程語言編寫的,就有了某些人通過在 web 查詢參數中使用 MySQL 語句嘗試 SQL 注入攻擊的風險。通過在參數中插入有害的 SQL 代碼片段,攻擊者會嘗試進入(或破壞)你的服務器。

假如說你有一個最終會放入變量 $product 的表單參數,你使用了類似下面的 SQL 語句:

$sql = "select * from pinfo where product = '$product'";

如果參數是直接從表單中獲得的,應該使用 PHP 自帶的數據庫特定轉義函數,類似:

$sql = 'Select * from pinfo where product = '"' mysql_real_escape_string($product) . '"';

如果不這樣做的話,有人也許會把下面的代碼段放到表單參數中:

39'; DROP pinfo; SELECT 'FOO

那么 $sql 的結果就是:

select product from pinfo where product = '39'; DROP pinfo; SELECT 'FOO'

由于分號是 MySQL 的語句分隔符,數據庫會運行下面三條語句:

select * from pinfo where product = '39'
DROP pinfo
SELECT 'FOO'

好了,你丟失了你的表。

注意實際上 PHP 和 MySQL 不會運行這種特殊語法,因為 mysql_query() 函數只允許每個請求處理一個語句。但是,一個子查詢仍然會生效。

要防止 SQL 注入攻擊,做這兩件事:

  • 總是驗證所有參數。例如,如果需要一個數字,就要確保它是一個數字。
  • 總是對數據使用 mysql_real_escape_string() 函數轉義數據中的任何引號和雙引號。

注意:要自動轉義任何表單數據,可以啟用魔術引號(Magic Quotes)。

一些 MySQL 破壞可以通過限制 MySQL 用戶權限避免。任何 MySQL 賬戶可以限制為只允許對選定的表進行特定類型的查詢。例如,你可以創建只能選擇行的 MySQL 用戶。但是,這對于動態數據并不十分有用,另外,如果你有敏感的用戶信息,可能某些人能訪問其中一些數據,但你并不希望如此。例如,一個訪問賬戶數據的用戶可能會嘗試注入訪問另一個人的賬戶號碼的代碼,而不是為當前會話指定的號碼。

防止基本的 XSS 攻擊

XSS 表示跨站腳本。不像大部分攻擊,該漏洞發生在客戶端。XSS 最常見的基本形式是在用戶提交的內容中放入 JavaScript 以便偷取用戶 cookie 中的數據。由于大部分站點使用 cookie 和 session 驗證訪客,偷取的數據可用于模擬該用戶-如果是一個常見的用戶賬戶就會深受麻煩,如果是管理員賬戶甚至是徹底的慘敗。如果你不在站點中使用 cookie 和 session ID,你的用戶就不容易被攻擊,但你仍然應該明白這種攻擊是如何工作的。

不像 MySQL 注入攻擊,XSS 攻擊很難預防。Yahoo、eBay、Apple、以及 Microsoft 都曾經受 XSS 影響。盡管攻擊不包含 PHP,但你可以使用 PHP 來剝離用戶數據以防止攻擊。為了防止 XSS 攻擊,你應該限制和過濾用戶提交給你站點的數據。正是因為這個原因,大部分在線公告板都不允許在提交的數據中使用 HTML 標簽,而是用自定義的標簽格式代替,例如[b][linkto]

讓我們來看一個如何防止這類攻擊的簡單腳本。對于更完善的解決辦法,可以使用 SafeHTML,本文的后面部分會討論到。

function transform_HTML($string, $length = null) {
// Helps prevent XSS attacks// Remove dead space.$string = trim($string);// Prevent potential Unicode codec problems.$string = utf8_decode($string);// HTMLize HTML-specific characters.$string = htmlentities($string, ENT_NOQUOTES);$string = str_replace("#", "#", $string);$string = str_replace("%", "%", $string);$length = intval($length);if ($length > 0) {$string = substr($string, 0, $length);}return $string;
}

這個函數將 HTML 特定的字符轉換為 HTML 字面字符。一個瀏覽器對任何通過這個腳本的 HTML 以非標記的文本呈現。例如,考慮下面的 HTML 字符串:

<STRONG>Bold Text</STRONG>

一般情況下,HTML 會顯示為:Bold Text

但是,通過 transform_HTML() 后,它就像原始輸入一樣呈現。原因是處理的字符串中的標簽字符串轉換為 HTML 實體。transform_HTML() 的結果字符串的純文本看起來像下面這樣:

<STRONG>Bold Text</STRONG>

該函數的實質是 htmlentities() 函數調用,它會將 <、>、和 & 轉換為 <>、和&。盡管這會處理大部分的普通攻擊,但有經驗的 XSS 攻擊者有另一種把戲:用十六進制或 UTF-8 編碼惡意腳本,而不是采用普通的 ASCII 文本,從而希望能繞過你的過濾器。他們可以在 URL 的 GET 變量中發送代碼,告訴瀏覽器,“這是十六進制代碼,你能幫我運行嗎?” 一個十六進制例子看起來像這樣:

<a href="http://host/a.php?variable=%22%3e %3c%53%43%52%49%50%54%3e%44%6f%73%6f%6d%65%74%68%69%6e%67%6d%61%6c%69%63%69%6f%75%73%3c%2f%53%43%52%49%50%54%3e">

瀏覽器渲染這個信息的時候,結果就是:

<a href="http://host/a.php?variable="> <SCRIPT>Dosomethingmalicious</SCRIPT>

為了防止這種情況,transform_HTML() 采用額外的步驟把 # 和 % 符號轉換為它們的實體,從而避免十六進制攻擊,并轉換 UTF-8 編碼的數據。

最后,為了防止某些人用很長的輸入超載字符串從而導致某些東西崩潰,你可以添加一個可選的 $length 參數來截取你指定最大長度的字符串。

使用 SafeHTML

之前腳本的問題比較簡單,它不允許任何類型的用戶標記。不幸的是,這里有上百種方法能使 JavaScript 跳過用戶的過濾器,并且要從用戶輸入中剝離全部 HTML,還沒有方法可以防止這種情況。

當前,沒有任何一個腳本能保證無法被破解,盡管有一些確實比大部分要好。有白名單和黑名單兩種方法加固安全,白名單比較簡單而且更加有效。

一個白名單解決方案是 PixelApes 的 SafeHTML 反跨站腳本解析器。

SafeHTML 能識別有效 HTML,能追蹤并剝離任何危險標簽。它用另一個稱為 HTMLSax 的軟件包進行解析。

按照下面步驟安裝和使用 SafeHTML:

  1. 到 http://pixel-apes.com/safehtml/?page=safehtml 下載最新版本的 SafeHTML。
  2. 把文件放到你服務器的類文件夾。該文件夾包括 SafeHTML 和 HTMLSax 功能所需的所有東西。
  3. 在腳本中 include SafeHTML 類文件(safehtml.php)。
  4. 創建一個名為 $safehtml 的新 SafeHTML 對象。
  5. 用 $safehtml->parse() 方法清理你的數據。

這是一個完整的例子:

<?php
/* If you're storing the HTMLSax3.php in the /classes directory, alongwith the safehtml.php script, define XML_HTMLSAX3 as a null string. */
define(XML_HTMLSAX3, '');
// Include the class file.
require_once('classes/safehtml.php');
// Define some sample bad code.
$data = "This data would raise an alert ";
// Create a safehtml object.
$safehtml = new safehtml();
// Parse and sanitize the data.
$safe_data = $safehtml->parse($data);
// Display result.
echo 'The sanitized data is 
' . $safe_data;
?>

如果你想清理腳本中的任何其它數據,你不需要創建一個新的對象;在你的整個腳本中只需要使用 $safehtml->parse() 方法。

什么可能會出現問題?

你可能犯的最大錯誤是假設這個類能完全避免 XSS 攻擊。SafeHTML 是一個相當復雜的腳本,幾乎能檢查所有事情,但沒有什么是能保證的。你仍然需要對你的站點做參數驗證。例如,該類不能檢查給定變量的長度以確保能適應數據庫的字段。它也不檢查緩沖溢出問題。

XSS 攻擊者很有創造力,他們使用各種各樣的方法來嘗試達到他們的目標。可以閱讀 RSnake 的 XSS 教程http://ha.ckers.org/xss.html ,看一下這里有多少種方法嘗試使代碼跳過過濾器。SafeHTML 項目有很好的程序員一直在嘗試阻止 XSS 攻擊,但無法保證某些人不會想起一些奇怪和新奇的方法來跳過過濾器。

注意:XSS 攻擊嚴重影響的一個例子 http://namb.la/popular/tech.html,其中顯示了如何一步一步創建一個讓 MySpace 服務器過載的 JavaScript XSS 蠕蟲。

用單向哈希保護數據

該腳本對輸入的數據進行單向轉換,換句話說,它能對某人的密碼產生哈希簽名,但不能解碼獲得原始密碼。為什么你希望這樣呢?應用程序會存儲密碼。一個管理員不需要知道用戶的密碼,事實上,只有用戶知道他/她自己的密碼是個好主意。系統(也僅有系統)應該能識別一個正確的密碼;這是 Unix 多年來的密碼安全模型。單向密碼安全按照下面的方式工作:

  1. 當一個用戶或管理員創建或更改一個賬戶密碼時,系統對密碼進行哈希并保存結果。主機系統會丟棄明文密碼。
  2. 當用戶通過任何方式登錄到系統時,再次對輸入的密碼進行哈希。
  3. 主機系統丟棄輸入的明文密碼。
  4. 當前新哈希的密碼和之前保存的哈希相比較。
  5. 如果哈希的密碼相匹配,系統就會授予訪問權限。

主機系統完成這些并不需要知道原始密碼;事實上,原始密碼完全無所謂。一個副作用是,如果某人侵入系統并盜取了密碼數據庫,入侵者會獲得很多哈希后的密碼,但無法把它們反向轉換為原始密碼。當然,給足夠時間、計算能力,以及弱用戶密碼,一個攻擊者還是有可能采用字典攻擊找出密碼。因此,別輕易讓人碰你的密碼數據庫,如果確實有人這樣做了,讓每個用戶更改他們的密碼。

加密 Vs 哈希

技術上來來說,哈希過程并不是加密。哈希和加密是不同的,這有兩個理由:

不像加密,哈希數據不能被解密。

是有可能(但非常罕見)兩個不同的字符串會產生相同的哈希。并不能保證哈希是唯一的,因此別像數據庫中的唯一鍵那樣使用哈希。

function hash_ish($string) {return md5($string);
}

上面的 md5() 函數基于 RSA 數據安全公司的消息摘要算法(即 MD5)返回一個由 32 個字符組成的十六進制串。然后你可以將那個 32 位字符串插入到數據庫中和另一個 md5 字符串相比較,或者直接用這 32 個字符。

破解腳本

幾乎不可能解密 MD5 數據。或者說很難。但是,你仍然需要好的密碼,因為用一整個字典生成哈希數據庫仍然很簡單。有一些在線 MD5 字典,當你輸入 06d80eb0c50b49a509b49f2424e8c805 后會得到結果 “dog”。因此,盡管技術上 MD5 不能被解密,這里仍然有漏洞,如果某人獲得了你的密碼數據庫,你可以肯定他們肯定會使用 MD5 字典破譯。因此,當你創建基于密碼的系統的時候尤其要注意密碼長度(最小 6 個字符,8 個或許會更好)和包括字母和數字。并確保這個密碼不在字典中。

用 Mcrypt 加密數據

如果你不需要以可閱讀形式查看密碼,采用 MD5 就足夠了。不幸的是,這里并不總是有可選項,如果你提供以加密形式存儲某人的信用卡信息,你可能需要在后面的某個地方進行解密。

最早的一個解決方案是 Mcrypt 模塊,這是一個用于允許 PHP 高速加密的插件。Mcrypt 庫提供了超過 30 種用于加密的計算方法,并且提供口令確保只有你(或者你的用戶)可以解密數據。

讓我們來看看使用方法。下面的腳本包含了使用 Mcrypt 加密和解密數據的函數:

<?php
$data = "Stuff you want encrypted";
$key = "Secret passphrase used to encrypt your data";
$cipher = "MCRYPT_SERPENT_256";
$mode = "MCRYPT_MODE_CBC";
function encrypt($data, $key, $cipher, $mode) {
// Encrypt data
return (string)base64_encode(mcrypt_encrypt($cipher,substr(md5($key),0,mcrypt_get_key_size($cipher, $mode)),$data,$mode,substr(md5($key),0,mcrypt_get_block_size($cipher, $mode))));
}
function decrypt($data, $key, $cipher, $mode) {
// Decrypt datareturn (string)mcrypt_decrypt($cipher,substr(md5($key),0,mcrypt_get_key_size($cipher, $mode)),base64_decode($data),$mode,substr(md5($key),0,mcrypt_get_block_size($cipher, $mode)));
}
?>

mcrypt() 函數需要幾個信息:

  • 需要加密的數據
  • 用于加密和解鎖數據的口令,也稱為鍵。
  • 用于加密數據的計算方法,也就是用于加密數據的算法。該腳本使用了 MCRYPT_SERPENT_256,但你可以從很多算法中選擇,包括MCRYPT_TWOFISH192MCRYPT_RC2MCRYPT_DES、和MCRYPT_LOKI97
  • 加密數據的模式。這里有幾個你可以使用的模式,包括電子密碼本(Electronic Codebook) 和加密反饋(Cipher Feedback)。該腳本使用MCRYPT_MODE_CBC 密碼塊鏈接。
  • 一個 初始化向量-也稱為 IV 或者種子,用于為加密算法設置種子的額外二進制位。也就是使算法更難于破解的額外信息。
  • 鍵和 IV 字符串的長度,這可能隨著加密和塊而不同。使用 mcrypt_get_key_size() mcrypt_get_block_size() 函數獲取合適的長度;然后用 substr() 函數將鍵的值截取為合適的長度。(如果鍵的長度比要求的短,別擔心,Mcrypt 會用 0 填充。)

如果有人竊取了你的數據和短語,他們只能一個個嘗試加密算法直到找到正確的那一個。因此,在使用它之前我們通過對鍵使用 md5() 函數增加安全,就算他們獲取了數據和短語,入侵者也不能獲得想要的東西。

入侵者同時需要函數,數據和口令,如果真是如此,他們可能獲得了對你服務器的完整訪問,你只能大清洗了。

這里還有一個數據存儲格式的小問題。Mcrypt 以難懂的二進制形式返回加密后的數據,這使得當你將其存儲到 MySQL 字段的時候可能出現可怕錯誤。因此,我們使用base64encode()base64decode() 函數轉換為和 SQL 兼容的字母格式和可檢索行。

破解腳本

除了實驗多種加密方法,你還可以在腳本中添加一些便利。例如,不用每次都提供鍵和模式,而是在包含的文件中聲明為全局常量。

生成隨機密碼

隨機(但難以猜測)字符串在用戶安全中很重要。例如,如果某人丟失了密碼并且你使用 MD5 哈希,你不可能,也不希望查找回來。而是應該生成一個安全的隨機密碼并發送給用戶。為了訪問你站點的服務,另外一個用于生成隨機數字的應用程序會創建有效鏈接。下面是創建密碼的一個函數:

<?phpfunction make_password($num_chars) {if ((is_numeric($num_chars)) &&($num_chars > 0) &&(! is_null($num_chars))) {$password = '';$accepted_chars = 'abcdefghijklmnopqrstuvwxyz1234567890';// Seed the generator if necessary.srand(((int)((double)microtime()*1000003)) );for ($i=0; $i<=$num_chars; $i++) {$random_number = rand(0, (strlen($accepted_chars) -1));$password .= $accepted_chars[$random_number] ;}return $password;}
}
?>

使用腳本

make_password() 函數返回一個字符串,因此你需要做的就是提供字符串的長度作為參數:

<?php
$fifteen_character_password = make_password(15);
?>

函數按照下面步驟工作:

  • 函數確保 $num_chars 是非零的正整數。
  • 函數初始化 $accepted_chars 變量為密碼可能包含的字符列表。該腳本使用所有小寫字母和數字 0 到 9,但你可以使用你喜歡的任何字符集合。(LCTT 譯注:有時候為了便于肉眼識別,你可以將其中的 0 和 O,1 和 l 之類的都去掉。)
  • 隨機數生成器需要一個種子,從而獲得一系列類隨機值(PHP 4.2 及之后版本中并不需要,會自動播種)。
  • 函數循環 $num_chars 次,每次迭代生成密碼中的一個字符。
  • 對于每個新字符,腳本查看 $accepted_chars 的長度,選擇 0 和長度之間的一個數字,然后添加 $accepted_chars 中該數字為索引值的字符到 $password。
  • 循環結束后,函數返回 $password

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/250650.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/250650.shtml
英文地址,請注明出處:http://en.pswp.cn/news/250650.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

day2-列表、元組、字典、字符串

1.列表&#xff08;list&#xff09; names[悟空,艾瑪,克林,龜仙人,天津飯,餃子,烏龜] print(names)---》列表&#xff0c;然后打印。 names[悟空,艾瑪,克林,龜仙人,天津飯,餃子,烏龜]# list section section1names[0] #下標從0開始 #print(section1) #結果為悟空seciton2names…

開漏輸出、推挽輸出的區別

推挽輸出:可以輸出高,低電平,連接數字器件。 輸出 0 時&#xff0c;N-MOS 導通&#xff0c;P-MOS 高阻&#xff0c;輸出0。 輸出 1 時&#xff0c;N-MOS 高阻&#xff0c;P-MOS 導通&#xff0c;輸出1&#xff08;不需要外部上拉電路&#xff09;。 開漏輸出:輸出端相當于三極管…

羅馬數字

古羅馬帝國開創了輝煌的人類文明&#xff0c;但他們的數字表示法的確有些繁瑣&#xff0c;尤其在表示大數的時候&#xff0c;現在看起來簡直不能忍受&#xff0c;所以在現代很少使用了。之所以這樣&#xff0c;不是因為發明表示法的人的智力的問題&#xff0c;而是因為一個宗教…

匯編 --- 從磁盤(扇區2到18)上讀取數據到內存中

下面代碼讀取柱面:0,磁頭:0,扇區從2到18的數據到內存 0x8200~0xa3ff處 需要明白以下幾點: 給定柱面,磁頭,一個扇形區域是512字節,對應的物理可以理解為512個燈泡組(一個燈泡組有8個小燈泡)確定讀取到內存中的位置 為什么是0x8200:因為0x8000~0x81ff這512個字節要留給啟動區.為…

那些值得思考的PHP問題

那些值得思考的PHP問題 1、關于弱類型 函數strpos是返回字符串str2在str1的位置&#xff0c;沒有找到則返回false&#xff0c;然而如果在實際應用上返回的位置是0&#xff0c;在if語句中0也被當作false&#xff0c;所以我們需要對false做類型判斷&#xff0c; $str1 yabadaba…

Lvs Tun隧道模式配置

######## TUN是IP Tunneling &#xff0c;IP隧道的簡稱&#xff0c;它將調度器收到的IP數據包封裝在一個新的IP數據包中&#xff0c;轉交給應用服務器&#xff0c;然后實際服務器的返回數據會直接返回給用戶。 工作原理&#xff1a; 用戶請求負載均衡服務器&#xff0c;當IP數…

mysql-常用sql

記錄下工作中常用的sql 刪除重復數據 delete from student where id not in (select min(id) from student group by name); -- 該語句在mysql下會報錯&#xff0c; -- 執行報錯&#xff1a;1093 - You cant specify target table student for update in FROM clause -- 原因是…

優雅的使用Laravel之phpstorm配置

優雅的使用Laravel之phpstorm配置 先打開一個Laravel 項目&#xff0c;然后在project tool 窗口選擇根節點、然后右鍵->Composer | Init composer 。 如果你的電腦里沒有composer.phar&#xff0c;可以點擊鏈接來下載。然后點擊項目 composer->add denpendency.. 搜索ba…

算法 --- 求兩個集合的并集

const unionL (l1, l2)>{for(let i0; i <l1.length; i){if(l2.indexOf(l1[i]) -1){l2.push(l1[i])}}return l2 }let l1 [1,2,3,4]; let l2 [1,2,5]; console.log(unionL(l1,l2)); //[1, 2, 5, 3, 4]

java實驗四——找鞍點

package hello;public class 實驗四 {public static void main(String[] args) {// TODO Auto-generated method stubint[][] a {{9,8,6},{2,3,1},{8,5,2}};System.out.println("二維數組為&#xff1a;");for(int i0;i<a.length;i){for(int j0;j<a[i].length;…

BZOJ 4551樹題解

好吧&#xff0c;洛谷的數據比較水暴力就可以過。。。。&#xff08;而且跑到飛快&#xff09; 不過&#xff08;BZ水不過去&#xff09;還是講講正規的做法。 其實一眼可以看出可以樹剖&#xff0c;但是&#xff0c;碼起來有點麻煩。 其實有一種更簡單的離線做法。 我們很容易…

es6 --- 使用Symbol保護私有變量

定義一個人物類 假設其屬性有姓名和性別我們希望,性別在聲明后就固定不變 傳統方法 var Person (function(){var _gender ;function P(name, gender){this.name name;_gender gender;}P.prototype.getGender function(){return _gender;}return P; })();var p1 new Pe…

組合數

long long factorial(int n) {long long m 1;for(int i1;i<n;i)m*i;return m; } long long C(int n,int m) {return factorial(n)/(factorial(m)*factorial(n-m));//可能會溢出 } 正解&#xff1a; long long C(int n,int m) {if(m<n-m) m n-m;long long ans 1;for(in…

Mysql中的聯合索引、前綴索引、覆蓋索引

Mysql中的聯合索引、前綴索引、覆蓋索引 索引 索引是一種特殊的文件&#xff0c;它們包含著對數據表里所有記錄的引用指針。更通俗的說&#xff0c;數據庫索引好比是一本書前面的目錄&#xff0c;能加快數據庫的查詢速度。 聯合索引 又名復合索引&#xff0c;由兩個或多個列…

LVM邏輯卷管理

什么是邏輯卷&#xff1f;因為可以將文件系統像卷一樣伸長或縮短之故。 LVM做法&#xff0c;將幾個物理分區或磁盤&#xff0c;通過軟件組合成為一塊看起來是獨立的大磁盤&#xff08;VG&#xff09;&#xff0c;然后將這塊大磁盤再經過分成可使用分區&#xff08;LV&#xff0…

es6 --- 自制迭代器

對象 對象如下 const obj {left: 100,top: 200 }不可迭代 for(let attr of obj){console.log(attr); }迭代規則 可迭代,所具有的屬性[Symbol.iterator] 需要自己給obj添加迭代規則 obj[Symbol.iterator] () >{// 獲取obj的所有鍵let keys Object.keys(obj);let len …

軟件工程的實踐項目課程的自我目標

對實踐項目完成后學習到的能力的預期&#xff1a;這算是自己第一次參加的團隊合作的軟件實踐吧&#xff0c;以前自己搞的小“玩意”&#xff0c;實難登大雅之堂&#xff0c;期待實踐項目后--->1、自己的代碼能力能夠有較明顯的提高&#xff0c;代碼更加規范。 2、提升團隊合…

[Shell] swoole_timer_tick 與 crontab 實現定時任務和監控

手動完成 "任務" 和 "監控" 主要有下面三步&#xff1a; 1. mission_cron.php&#xff08;定時自動任務腳本&#xff09;&#xff1a; <?php /*** 自動任務 定時器 (5s 執行).** swoole_timer_tick 解決秒級定時&#xff1b;* 如需調整&#xff0c;注意…

關于項目調研

一、檸檬時代app 1、作品內容&#xff1a; 該作品主要為每一所高校的大學生量身定制的手機生活助手&#xff0c;由您自主運營的校園手機客戶端。開放的自定義平臺&#xff0c;匯聚本校周邊所有生活服務、外賣商家、娛樂休閑、新鮮事兒、知名社團、周邊商鋪、校園達人等欄目。 …

html 標簽

html概述 超文本標記語言&#xff08;英語&#xff1a;HyperText Markup Language&#xff0c;簡稱&#xff1a;HTML&#xff09;是一種用于創建網頁的標準標記語言。HTML是一種基礎技術&#xff0c;常與CSS、JavaScript一起被眾多網站用于設計令人賞心悅目的網頁、網頁應用程序…