Grsecurity/如何貢獻
最簡單的貢獻方式是透過糾正拼寫錯誤或重構句子或段落以使其更易讀來增強現有內容。您也歡迎新增新內容,方法是擴充套件正在開發中的頁面,或者如果您新增的文字不適合其他任何頁面,則新增全新的頁面。由於 grsecurity 正在積極開發中,並且功能在不斷新增和刪除,因此非常感謝您幫助保持內容的最新狀態。
在本頁,您將找到有關為何為本書選擇特定結構的背景資訊、本書的受眾以及應使用哪種風格和格式。
本書的結構遵循 grsecurity 專案的原始文件,該文件包含三個主要章節:安裝、配置和規範以及使用 gradm 和學習模式。配置和規範被重新命名為策略配置。使用 gradm 和學習模式被重新命名為管理,並且也被移到策略配置之前,因為您必須瞭解如何在配置策略之前管理 grsecurity。這就是我們最終得到核心結構的方式:安裝、管理、策略配置。
本書面向能夠獨立解決不同複雜程度的硬體和軟體問題,並且真正閱讀手冊的人。他們熟悉自己喜歡的 Linux 發行版,並且熟悉從原始碼配置和構建軟體。
本書旨在提供全面、可靠和最新的 grsecurity 及相關工具文件。除了教授如何做某事之外,本書還提供了有關實踐中學習到的最佳實踐和常見陷阱的資訊。這是主要目標。
每個章節都有額外的目標,這些目標定義了讀者在閱讀完章節後應該瞭解的內容。這些目標是在本書大部分核心內容到位後定義的,因此在撰寫本文時,某些章節可能無法滿足所有目標。
簡介 - 讀者必須在基本層面上了解什麼是 grsecurity,它的目標是什麼以及這些目標是如何實現的。如果他們不屬於我們的目標受眾,他們仍然應該對 grsecurity 的基本內容有一個大致瞭解。
安裝 - 讀者必須瞭解
- 從哪裡獲取 grsecurity、它的管理工具 gradm 以及 Linux 核心原始碼。
- 如何驗證每個軟體包的真實性。
- 如何正確應用 grsecurity 補丁。
- 如何配置 grsecurity 的核心配置選項(這包括 PaX 設定),以及在執行此操作之前需要考慮哪些因素。
- 如何使用他們選擇的發行版的工具構建和安裝啟用 grsecurity 的核心。
管理 - 讀者必須瞭解
- 如何安裝管理工具 gradm。
- 如何使用 gradm,尤其是學習模式。
- 如何配置 grsecurity 的執行時功能。
- 還提供了哪些其他有用工具,從哪裡獲取這些工具,以及如何安裝和使用這些工具。
- 如何解決應用程式相容性問題和 grsecurity 問題。
策略配置 - 讀者必須瞭解
- 什麼是 RBAC 系統以及它不是什麼,在正確配置後它可以提供什麼。
- 什麼構成了一個安全策略。
- 策略結構和規則;他們必須熟悉每個配置元素及其引數和配置繼承。
報告錯誤:讀者必須瞭解如何報告錯誤;需要哪些資訊,如何收集這些資訊以及將報告發送到哪裡。
- 標題應為標題大小寫。
- 使用<pre> 標籤顯示長命令、示例程式輸出和檔案內容。
- 當您需要指出重要的安全注意事項或可能危險的操作時,請使用XWarning 模板。滾動時,它比經典的Warning 模板更容易發現。
- 當您需要指出與周圍文字相關的內容時,請使用Info 模板。
- 名稱 grsecurity 應寫成小寫,並且不使用特殊格式,除非它是一個句子的開頭。這就是它在 grsecurity 網站上的寫法。
注意:這仍然是一個正在進行的工作,將來會發生變化。它將很快完成。
- 斜體
- 用於檔案和目錄名稱。
- 粗體
- 用於偶爾強調,例如在介紹新術語時。
- 等寬字型
- 在文字中用於程式和命令名稱。預格式化文字塊用於顯示示例,顯示要執行的命令以及它們的輸出應該是什麼。
本書中的一些內容可以從 grsecurity 的原始檔中自動生成。執行此操作的指令碼和程式列在此處。歡迎對任何指令碼和程式的修復和改進,以及完整的重寫。
| 由於此頁面和指令碼可以由任何人修改,因此在執行任何程式碼之前,請務必檢查所有程式碼。 |
下面是一個Python 指令碼,它輸出兩個檔案,一個用於Grsecurity 和 PaX 配置選項 頁面,另一個用於Sysctl 選項 頁面。
該指令碼將修補了 grsecurity 的核心原始碼的絕對路徑作為輸入,讀取grsecurity/grsec_sysctl.c、security/Kconfig 和grsecurity/Kconfig 檔案,並輸出兩個名為Grsecurity_and_PaX_Configuration_Options.wiki 和Sysctl_Options.wiki 的檔案。Grsecurity_and_PaX_Configuration_Options.wiki 的內容可以原樣複製到維基百科。Sysctl_Options.wiki 僅包含可以顯示在Sysctl 選項 頁面上的表格中的連結分類列表。Sysctl_Options.wiki 檔案中的連結指向Grsecurity 和 PaX 配置選項 頁面上的錨點,因此這兩個檔案的內容是連結的。
該指令碼使用 Ulf Magnusson 編寫的Kconfiglib 來讀取 Kconfig 檔案。
您可以隨意用 Perl 單行程式或單個命令列替換該指令碼。
#!/usr/bin/env python
import sys
import codecs
import os
import kconfiglib
def get_sysctl_opts(kern_src_dir):
"""
Returns a dictionary of sysctl variables related to grsecurity.
Parameters:
kern_src_dir (string) Absolute path to a kernel source directory
(e.g. /usr/src/linux-3.2.48.)
The key of each item is the name of a kernel configuration symbol (e.g.
GRKERNSEC_SYMLINKOWN) and the value is a list of sysctl variable names
(e.g. [enforce_symlinksifowner, symlinkown_gid]).
"""
file_name = os.path.join(kern_src_dir, "grsecurity", "grsec_sysctl.c")
options = {}
with open(file_name, 'r') as f:
cur_symbol = None
for line in f:
if line.startswith("#ifdef"):
start = line.find("GRKERNSEC")
cur_symbol = line[start:].strip()
options[cur_symbol] = []
elif line.startswith("#endif"):
if cur_symbol in options:
options[cur_symbol].sort()
cur_symbol = None
if cur_symbol is not None and line.find(".procname") >= 0:
a = line.find('"') + 1
b = line.rfind('"')
sysctl_var = line[a:b].strip()
options[cur_symbol].append(sysctl_var)
return options
def get_categorized_sysctl_opts(sysctl_opts):
"""
Returns a list of lists or tuples.
Parameters:
sysctl_opts (dict) Dictionary of sysctl variables. This would be the
return value of get_sysctl_opts().
Each index in the returned list specifies a category. The categories are
[0] Audit/logging variables
[1] Chroot variables
[2] Network variables
[3] Misc. variables
The categorization is based on the name of the sysctl variable, and is
not entirely accurate. But it's "good enough."
Each category consists of a list of tuples. The first element of a tuple
is the name of a kernel configuration symbol (e.g. GRKERNSEC_SYMLINKOWN)
and the second element is a sysctl variable that is related to that
symbol. If a symbol is related to more than one sysctl variable, the list
will contain multiple tuples that have the same first element.
"""
audit_opts = []
chroot_opts = []
net_opts = []
other_opts = []
for item in sysctl_opts.iteritems():
for opt in item[1]:
if opt.find("audit") >= 0 or opt.find("log") >= 0:
audit_opts.append((opt,item[0]))
elif opt.find("chroot") >= 0:
chroot_opts.append((opt,item[0]))
elif opt.find("socket") >= 0 or opt.find("ip") >= 0:
net_opts.append((opt,item[0]))
else:
other_opts.append((opt,item[0]))
audit_opts.sort()
chroot_opts.sort()
net_opts.sort()
other_opts.sort()
all_opts = [audit_opts, chroot_opts, net_opts, other_opts]
return all_opts
def write_wikified_sysctl_opts(kern_src_dir, out_file_name):
"""
Writes a categorized list of sysctl variables wrapped in MediaWiki links
constructs.
Parameters:
kern_src_dir (string) Absolute path to a kernel source directory
(e.g. /usr/src/linux-3.2.48.)
out_file_name (string) Path and file name or just the file name of the
output file.
The links point to anchors on the Grsecurity and PaX Configuration Options
page. The links are written in alphabetical order by the sysctl variable.
"""
sysctl_opts = get_sysctl_opts(kern_src_dir)
categorized_opts = get_categorized_sysctl_opts(sysctl_opts)
kconfig_path = os.path.join(kern_src_dir, "security", "Kconfig")
conf = kconfiglib.Config(kconfig_path, kern_src_dir)
link_fmt = "* [[Grsecurity/Appendix/Grsecurity_and_PaX"\
"_Configuration_Options#{0}|{1}]]\n"
with codecs.open(out_file_name, 'w', "utf-8") as f:
f.write("Category: Audit/logging\n")
for opt in categorized_opts[0]:
symbol = conf.get_symbol(opt[1])
prompt = get_prompt(symbol)
f.write(link_fmt.format(prompt, opt[0]))
f.write("\nCategory: Chroot\n")
for opt in categorized_opts[1]:
symbol = conf.get_symbol(opt[1])
prompt = get_prompt(symbol)
f.write(link_fmt.format(prompt, opt[0]))
f.write("\nCategory: Network\n")
for opt in categorized_opts[2]:
symbol = conf.get_symbol(opt[1])
prompt = get_prompt(symbol)
f.write(link_fmt.format(prompt, opt[0]))
f.write("\nCategory: Miscellaneous\n")
for opt in categorized_opts[3]:
symbol = conf.get_symbol(opt[1])
prompt = get_prompt(symbol)
f.write(link_fmt.format(prompt, opt[0]))
def get_prompt(item):
"""
Return the first prompt text of the specified symbol or choice.
Parameters:
item (Kconfiglib.Symbol or Kconfiglib.Choice) The object whose
prompt is to be returned.
Kconfiglib does not expose the prompt(s) of a Symbol or Choice. They have
to be extracted from the string representation of a Symbol object. This
function only returns the first prompt. There may be more prompts and
they may or may not be identical.
"""
s = str(item)
prefix = "Prompts:"
i = s.find(prefix)
prompt = None
if i >= 0:
a = s.find('"', i + len(prefix)) + 1
b = s.find('"', a)
prompt = s[a:b]
return prompt
def write_wikified_item(f, sysctl_opts, item, level):
"""
Write the given Kconfiglib.Item in the specified file.
Parameters:
f (file) Output file object open for writing.
sysctl_opts (dict) Dictionary of sysctl variables. This would be the
return value of get_sysctl_opts().
item (Kconfiglib.Item) Item that should be formatted.
level (integer) Heading level (number of '=' characters before
and after a heading). Items are hierarchical and this
function will increment the level when it calls itself
recursively to process child Items.
This function wraps certain properties of item and related content from
sysctl_opts in MediaWiki markup and writes the output to the specified
file object.
If item is a Menu, it is formatted as a heading and its child Items
are iterated and formatted.
If item is a Choice, its prompt text is formatted as a heading and
help text as preformatted text.
If item is a Symbol, its prompt text is formatted as a heading, name as
teletype text, help text as preformatted text and all related sysctl
options as intended lines below a sort of heading that's regular
unformatted text.
"""
heading_fmt = "\n{0}{1}{0}\n"
symbol_fmt = "<tt>{0}</tt><br/>\n"
help_fmt = "<pre>{0}</pre>\n"
sysctl_vars_heading = "Related sysctl variables:<br/>\n"
sysctl_var_fmt = ":<tt>kernel.grsecurity.{0}</tt>\n"
if item.is_menu():
if level > 1:
f.write(heading_fmt.format("=" * level, item.get_title()))
for subitem in item.get_items():
write_wikified_item(f, sysctl_opts, subitem, level + 1)
if item.is_choice():
f.write(heading_fmt.format("=" * level, get_prompt(item)))
help_text = item.get_help()
if help_text is not None and len(help_text) > 0:
f.write(help_fmt.format(help_text.strip()))
for subitem in item.get_items():
write_wikified_item(f, sysctl_opts, subitem, level + 1)
if item.is_symbol():
name = item.get_name().strip()
prompt = get_prompt(item)
help_text = item.get_help()
if prompt is not None and len(prompt) >= 3:
f.write(heading_fmt.format("=" * level, prompt))
f.write(symbol_fmt.format(name))
if name in sysctl_opts:
opt_list = sysctl_opts[name]
if opt_list is not None and len(opt_list) > 0:
f.write(sysctl_vars_heading)
for opt in sysctl_opts[name]:
f.write(sysctl_var_fmt.format(opt))
if help_text is not None and len(help_text) > 0:
f.write(help_fmt.format(help_text.strip()))
def write_wikified_kconfig(kern_src_dir, out_file_name):
"""
Create a MediaWiki-formatted version of the Kconfig file found in
the kern_src_dir/security/ directory and write the output to the
given file.
Parameters:
kern_src_dir (string) Absolute path to a kernel source directory
(e.g. /usr/src/linux-3.2.48.)
out_file_name (string) Path and file name or just the file name of the
output file.
"""
security_kconfig = os.path.join(kern_src_dir, "security", "Kconfig")
conf = kconfiglib.Config(security_kconfig, kern_src_dir)
if conf is not None:
for menu in conf.get_menus():
if menu.get_title() == "Grsecurity":
with codecs.open(out_file_name, 'w', "utf-8") as f:
sysctl_opts = get_sysctl_opts(kern_src_dir)
write_wikified_item(f, sysctl_opts, menu, 1)
break
# kern_src_dir is expected to be an absolute path to the kernel
# source directory (e.g. /usr/src/linux-3.2.48).
kern_src_dir = sys.argv[1]
if kern_src_dir is not None and len(kern_src_dir) > 0:
write_wikified_kconfig(kern_src_dir,
"Grsecurity_and_PaX_Configuration_Options.wiki")
write_wikified_sysctl_opts(kern_src_dir, "Sysctl_Options.wiki")