0Pricing
DevOps Bootcamp · บทเรียน

การป้องกันการแทรกคำสั่งและอาร์กิวเมนต์

ใส่เครื่องหมายคำพูด ตรวจสอบ และส่งอินพุตที่ไม่น่าเชื่อถือผ่านอาร์เรย์ เพื่อกำจัดการแยกคำและการแทรกผ่าน eval

การป้องกันการแทรกคำสั่งและอาร์กิวเมนต์ เป็นบทเรียน DevOps Bootcamp ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน DevOps Bootcamp และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส DevOps Bootcamp มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดการโจมตีแบบฉีดคำสั่งจึงเกิดขึ้นใน Bash

Bash เป็นภาษาสำหรับเชื่อมการทำงานที่ทรงพลัง — โดยส่งข้อความโดยตรงไปยังเคอร์เนล โปรแกรมอื่น และเชลล์ย่อย พลังนี้จะกลายเป็นจุดอ่อนทันทีเมื่อข้อมูลอินพุตที่ไม่น่าเชื่อถือไปถึงคำสั่งโดยไม่มีการตรวจสอบหรือใส่เครื่องหมายอัญประกาศ

สาเหตุรากฐานสองประการทำให้เกิดการฉีดคำสั่งใน Bash เกือบทุกกรณี:

  • การแยกคำ: ตัวแปรที่ไม่ใส่เครื่องหมายอัญประกาศจะถูกแยกตามช่องว่าง (IFS) ทำให้ค่าหนึ่งค่าที่มีความหมายเดียวกลายเป็นโทเค็นของเชลล์หลายรายการ
  • การขยายโกลบ: เชลล์จะขยายอักขระอย่าง *, ? และ [ ก่อนที่คำสั่งจะเริ่มทำงานเสียอีก

ผู้โจมตีที่ควบคุมชื่อไฟล์ ชื่อผู้ใช้ พารามิเตอร์ URL หรือตัวแปรสภาพแวดล้อม สามารถใช้ประโยชน์จากทั้งสองช่องทางเพื่อเรียกใช้คำสั่งใด ๆ อ่านไฟล์ หรือยกระดับสิทธิ์ได้

บทเรียนนี้จะแสดงอย่างชัดเจนว่าช่องโหว่เหล่านี้ปรากฏขึ้นได้อย่างไร และที่สำคัญกว่านั้นคือวิธีกำจัดช่องโหว่ด้วยการใส่เครื่องหมายอัญประกาศอย่างถูกต้อง การตรวจสอบอินพุต และการส่งอาร์กิวเมนต์โดยใช้อาร์เรย์

การแยกคำ: ภัยเงียบที่ต้องระวัง

เมื่อ Bash พบตัวแปรที่ไม่ใส่เครื่องหมายอัญประกาศ มันจะแยกค่าตามอักขระใด ๆ ที่ระบุไว้ใน $IFS (ค่าเริ่มต้น: ช่องว่าง แท็บ การขึ้นบรรทัดใหม่) สิ่งที่ดูเหมือนอาร์กิวเมนต์เดียวจะกลายเป็นหลายรายการ

เรียกใช้สคริปต์ด้านล่างและสังเกตว่าชื่อไฟล์ที่มีช่องว่างกลายเป็นอาร์กิวเมนต์แยกกันสองรายการของ rm ได้อย่างไร

#!/usr/bin/env bash
# Dangerous: unquoted variable
FILE='important file.txt'

# Create the file so the demo is self-contained
touch "$FILE"

echo "Files before:"
ls

# BUG: rm sees TWO arguments: 'important' and 'file.txt'
# If 'important' does not exist, rm prints an error but continues.
rm $FILE   # <-- unquoted, word-split happens here

echo "Files after (unquoted rm):"
ls

ใส่เครื่องหมายอัญประกาศเสมอ: กฎข้อแรกของ Bash เชิงป้องกัน

วิธีป้องกันการแยกคำที่ง่ายและมีประสิทธิภาพที่สุดคือใส่เครื่องหมายอัญประกาศคู่ให้กับการขยายค่าตัวแปรเสมอ

  • "$var" — ขยายเป็นโทเค็นเดียวพอดี โดยรักษาช่องว่าง แท็บ และการขึ้นบรรทัดใหม่ไว้
  • 'literal' — เครื่องหมายอัญประกาศเดี่ยว: ไม่มีการขยายใด ๆ เหมาะสำหรับสตริงคงที่
  • อย่าใช้ $var โดยไม่ใส่เครื่องหมายอัญประกาศ เว้นแต่คุณต้องการการแยกคำและการขยายโกลบโดยเฉพาะ

สคริปต์ด้านล่างแสดงเวอร์ชันที่ปลอดภัยของตัวอย่างก่อนหน้า

#!/usr/bin/env bash
set -euo pipefail

FILE='important file.txt'
touch "$FILE"

echo 'Files before:'
ls

# SAFE: double-quotes keep the filename as one token
rm "$FILE"

echo 'Files after (quoted rm):'
ls

การฉีดโกลบ: เมื่อ * กลายเป็นอาวุธ

ตัวแปรที่ไม่ใส่เครื่องหมายอัญประกาศยังอยู่ภายใต้การขยายชื่อพาธ (โกลบ) ด้วย หากข้อมูลอินพุตที่ผู้ใช้ควบคุมมี * หรือ ? Bash จะขยายค่าดังกล่าวโดยเทียบกับระบบไฟล์ก่อนที่คำสั่งจะทำงาน

ช่องทางการโจมตีแบบคลาสสิก: แบบฟอร์มเว็บกำหนดให้ PATTERN=* และสคริปต์เรียกใช้ cp $PATTERN /tmp/leak/ — ส่งสำเนาของทุกไฟล์ในไดเรกทอรีปัจจุบัน

วิธีแก้เหมือนเดิม: ใส่เครื่องหมายอัญประกาศคู่ให้ตัวแปร ค่า "$PATTERN" ที่ใส่เครื่องหมายอัญประกาศจะถูกส่งไปตามตัวอักษร เชลล์จะไม่ทำการขยายโกลบกับค่านี้

#!/usr/bin/env bash
set -euo pipefail

# Simulate attacker-supplied input
PATTERN='*'

mkdir -p /tmp/safe_demo_src /tmp/safe_demo_dst
touch /tmp/safe_demo_src/secret1.txt /tmp/safe_demo_src/secret2.txt

cd /tmp/safe_demo_src

# UNSAFE: glob expands, copies every file
# cp $PATTERN /tmp/safe_demo_dst/

# SAFE: pattern is treated as a literal filename
cp "$PATTERN" /tmp/safe_demo_dst/ 2>&1 || echo 'No file named literally "*" — attack neutralised'

rm -rf /tmp/safe_demo_src /tmp/safe_demo_dst

การฉีดอาร์กิวเมนต์ผ่านพารามิเตอร์ตามตำแหน่งที่ไม่ใส่เครื่องหมายอัญประกาศ

สคริปต์ที่รับอาร์กิวเมนต์จากผู้เรียกใช้เป็นเป้าหมายชั้นดีสำหรับการฉีดคำสั่ง พารามิเตอร์ตามตำแหน่งแต่ละรายการ ($1, $2, ...) ต้องใส่เครื่องหมายอัญประกาศทุกครั้งที่นำไปใช้

รูปแบบที่อันตรายเป็นพิเศษคือการส่ง $@ หรือ $* โดยไม่ใส่เครื่องหมายอัญประกาศไปยังคำสั่งอื่น:

  • "$@" — ขยายพารามิเตอร์ตามตำแหน่งแต่ละรายการเป็นคำที่แยกจากกันและใส่เครื่องหมายอัญประกาศเป็นรายรายการ ใช้รูปแบบนี้เสมอ
  • $@ หรือ $* ที่ไม่ใส่เครื่องหมายอัญประกาศ — อยู่ภายใต้การแยกคำและการขยายโกลบ
  • "$*" — รวมพารามิเตอร์ทั้งหมดเป็นคำเดียว (ซึ่งไม่ค่อยใช่สิ่งที่ต้องการ)
#!/usr/bin/env bash
set -euo pipefail

# Safe wrapper: forward all arguments quoted
grep_wrapper() {
    local pattern="$1"
    shift
    # "$@" preserves each file argument as one token
    grep -rn "$pattern" "$@"
}

# Usage: ./script 'error msg' /var/log/syslog '/path with spaces/app.log'
echo 'Searching current script for "safe":'
grep_wrapper 'safe' "$0"

การฉีดคำสั่งผ่าน eval และอินพุตที่ไม่ผ่านการตรวจสอบ

eval จะวิเคราะห์อาร์กิวเมนต์ของมันใหม่ในฐานะโค้ดเชลล์ ข้อมูลที่ไม่น่าเชื่อถือใด ๆ ที่ไปถึง eval สามารถเรียกใช้คำสั่งใด ๆ ได้

รูปแบบที่อันตรายที่พบบ่อย:

  • eval "$user_input"
  • eval echo \$$var (การค้นหาตัวแปรทางอ้อม)
  • การส่งข้อมูลผู้ใช้ผ่าน bash -c "$input"

กฎ: อย่าส่งอินพุตที่ไม่น่าเชื่อถือไปยัง eval หรือ bash -c เด็ดขาด ให้ใช้ทางเลือกที่ปลอดภัยของ Bash:

  • การขยายทางอ้อม: ${!varname} แทน eval echo \$$varname
  • อาร์เรย์เชื่อมโยงสำหรับการค้นหาคีย์-ค่าแบบไดนามิก
  • ฟังก์ชันแทนสตริงคำสั่งที่สร้างขึ้น
#!/usr/bin/env bash
set -euo pipefail

# Simulated attacker-supplied variable name
VARNAME='PATH; echo INJECTED'

# UNSAFE: eval lets attacker run 'echo INJECTED'
# eval "echo \$$VARNAME"

# SAFE: indirect expansion only resolves valid variable names
# First validate that VARNAME is a legal identifier
if [[ "$VARNAME" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then
    echo "Value: ${!VARNAME}"
else
    echo "ERROR: invalid variable name: '$VARNAME'" >&2
    exit 1
fi

การตรวจสอบอินพุต: ใช้รายการอนุญาตแทนรายการปฏิเสธ

การปฏิเสธอักขระที่ทราบว่าไม่ดี (เรียกว่ารายการปฏิเสธ) มีความเปราะบาง — ผู้โจมตีอาจค้นพบการเข้ารหัสหรืออักขระที่คุณลืมไว้ ดังนั้นให้ใช้รายการอนุญาต: ยอมรับเฉพาะอักขระที่คุณทราบว่าปลอดภัย

กลยุทธ์การใช้รายการอนุญาตใน Bash:

  • การจับคู่ด้วยนิพจน์ทั่วไป: [[ "$input" =~ ^[A-Za-z0-9_-]+$ ]]
  • การจับคู่รูปแบบ: case "$input" in [A-Za-z0-9]*) ... ;; esac
  • การตรวจสอบค่าแจกแจง: เปรียบเทียบกับชุดค่าที่ถูกต้องซึ่งกำหนดไว้ตายตัว

ตรวจสอบที่ขอบเขต — ทันทีที่อินพุตเข้าสู่สคริปต์ — ก่อนที่อินพุตจะถูกส่งให้คำสั่งใด ๆ

#!/usr/bin/env bash
set -euo pipefail

validate_username() {
    local name="$1"
    # Allowlist: only lowercase letters, digits, underscore, hyphen; 1-32 chars
    if [[ ! "$name" =~ ^[a-z0-9_-]{1,32}$ ]]; then
        echo "ERROR: invalid username '${name}'" >&2
        return 1
    fi
    echo "Username accepted: $name"
}

validate_username 'alice'          # OK
validate_username 'bob_smith-2'    # OK
validate_username 'root; rm -rf /' # REJECTED
validate_username '../etc/passwd'   # REJECTED

ใช้อาร์เรย์เพื่อส่งอาร์กิวเมนต์อย่างปลอดภัย

เมื่อคุณต้องสร้างคำสั่งแบบไดนามิก — เช่น เพิ่มแฟล็กตามเงื่อนไขหรือวนซ้ำกับอินพุต — ให้ใช้อาร์เรย์ Bash แทนการต่อสตริง

การต่อสตริงจะทำให้โครงสร้างทั้งหมดถูกรวมเข้าด้วยกัน แต่อาร์เรย์ Bash จะรักษาอาร์กิวเมนต์แต่ละรายการเป็นองค์ประกอบแยกจากกัน โดยไม่ให้เชลล์วิเคราะห์ซ้ำ

  • ประกาศ: args=()
  • เพิ่ม: args+=(--flag "$value")
  • เรียกใช้: command "${args[@]}"

"${args[@]}" จะขยายทุกองค์ประกอบเป็นคำที่แยกจากกันและใส่เครื่องหมายอัญประกาศเป็นรายรายการ — เช่นเดียวกับ "$@" ทุกประการ

#!/usr/bin/env bash
set -euo pipefail

# Build a find command safely with an array
BASEDIR='/tmp'
USER_PATTERN='*.log'   # could come from user input (validate first!)
MAX_DAYS=7

cmd=(find "$BASEDIR" -type f -name "$USER_PATTERN" -mtime "+${MAX_DAYS}")

# Optionally add -delete only when requested
DELETE=false
if [[ "$DELETE" == 'true' ]]; then
    cmd+=(-delete)
fi

echo "Running: ${cmd[*]}"
"${cmd[@]}"

ตัวคั่น --: การป้องกันการฉีดแฟล็ก

แม้แต่อาร์กิวเมนต์ที่ใส่เครื่องหมายอัญประกาศอย่างถูกต้องก็อาจถูกตีความผิดเป็นแฟล็กตัวเลือกได้ หากเริ่มต้นด้วย - ลองพิจารณา rm "$file" เมื่อ file='-rf .': การใส่เครื่องหมายอัญประกาศป้องกันการแยกคำ แต่ rm ยังคงตีความ -rf เป็นแฟล็ก

แบบแผนของ POSIX คือ -- ซึ่งส่งสัญญาณว่าสิ้นสุดตัวเลือกสำหรับยูทิลิตี GNU/BSD ส่วนใหญ่ ทุกสิ่งหลัง -- จะถูกถือเป็นอาร์กิวเมนต์ตามตำแหน่งและจะไม่ถูกตีความเป็นแฟล็ก

#!/usr/bin/env bash
set -euo pipefail

# Simulate a dangerous filename supplied by the user
FILENAME='-rf /tmp/safe_demo_target'

mkdir -p /tmp/safe_demo_target
touch /tmp/safe_demo_target/keep_me.txt

echo 'Files before:'
ls /tmp/safe_demo_target/

# UNSAFE (flag injection — do NOT uncomment in real systems):
# rm "$FILENAME"

# SAFE: -- ends option processing; filename is treated literally
rm -- "$FILENAME" 2>&1 || echo "No such file (attack neutralised): $FILENAME"

echo 'Files after:'
ls /tmp/safe_demo_target/
rm -rf /tmp/safe_demo_target

การทำให้อินพุตปลอดภัยสำหรับ SQL และเครื่องมือภายนอก

เมื่อสคริปต์ Bash เรียกใช้เครื่องมือบรรทัดคำสั่งของฐานข้อมูล (psql, mysql) เรียกใช้ curl พร้อม URL ที่ผู้ใช้ระบุ หรือเรียกใช้เครื่องมือที่คล้ายกัน จะมีชั้นการป้องกันเพิ่มเติมสองประการ:

  • คิวรีแบบมีพารามิเตอร์: อย่าแทรกข้อมูลผู้ใช้ลงในสตริง SQL โดยตรง ให้ส่งค่าผ่าน -v ใน psql หรือ --data-urlencode ใน curl
  • แยกข้อมูลออกจากโค้ด: ใช้ printf พร้อมสตริงรูปแบบคงที่ อย่าปล่อยให้อินพุตของผู้ใช้เป็นสตริงรูปแบบ

ตัวอย่างด้านล่างสอบถาม PostgreSQL อย่างปลอดภัย โดยเก็บค่าที่ผู้ใช้ระบุไว้นอกข้อความ SQL อย่างสมบูรณ์

#!/usr/bin/env bash
set -euo pipefail

# Validate first: only allow alphanumeric usernames
USERNAME="${1:-alice}"
if [[ ! "$USERNAME" =~ ^[a-z0-9_]{1,32}$ ]]; then
    echo 'ERROR: invalid username' >&2
    exit 1
fi

# UNSAFE:
# psql -c "SELECT * FROM users WHERE name = '$USERNAME';"

# SAFE: pass value as a psql variable, never inside the SQL text
# psql -v username="$USERNAME" -c 'SELECT * FROM users WHERE name = :username;'

# Demonstrate the principle with printf (safe format string usage)
printf 'Query would use username: %s\n' "$USERNAME"

รายการตรวจสอบการเสริมความปลอดภัย: รวมทุกอย่างเข้าด้วยกัน

สคริปต์ Bash ที่ปลอดภัยระดับใช้งานจริงจะรวมเทคนิคทั้งหมดจากบทเรียนนี้เข้าเป็นการป้องกันหลายชั้นที่สอดคล้องกัน ต่อไปนี้คือแม่แบบที่เสริมความปลอดภัยแล้ว ซึ่งมีขนาดเล็กแต่ครบถ้วน:

  • set -euo pipefail — ออกจากการทำงานเมื่อเกิดข้อผิดพลาด ถือว่าตัวแปรที่ไม่ได้ตั้งค่าเป็นข้อผิดพลาด และส่งต่อความล้มเหลวของไปป์
  • ตรวจสอบตั้งแต่ทางเข้า — ใช้รายการอนุญาตกับอินพุตภายนอกทุกรายการก่อนที่จะถูกส่งให้คำสั่งใด ๆ
  • ใส่เครื่องหมายอัญประกาศทุกอย่าง — "$var", "$@", "${array[@]}" — ไม่มีข้อยกเว้น เว้นแต่คุณต้องการการแยกคำ
  • ใช้อาร์เรย์ สำหรับการสร้างคำสั่งแบบไดนามิก
  • เติม -- หน้้าอาร์กิวเมนต์ เมื่อส่งชื่อไฟล์หรือสตริงที่ผู้ใช้ระบุ
  • อย่าใช้ eval เด็ดขาด กับข้อมูลที่ไม่น่าเชื่อถือ ให้เลือกใช้ ${!var} สำหรับการค้นหาทางอ้อม
  • จำกัดสิทธิ์ — เรียกใช้สคริปต์ด้วยสิทธิ์เท่าที่จำเป็น หลีกเลี่ยงการใช้ sudo ภายในสคริปต์ที่รับอินพุตจากผู้ใช้
#!/usr/bin/env bash
# Hardened template — safe argument injection prevention
set -euo pipefail
IFS=$'\n\t'

#--- 1. Validate inputs at the boundary ---
SEARCH_DIR="${1:-}"
PATTERN="${2:-}"

[[ -z "$SEARCH_DIR" || -z "$PATTERN" ]] && { echo 'Usage: script <dir> <pattern>' >&2; exit 1; }
[[ ! "$SEARCH_DIR" =~ ^[A-Za-z0-9/_.-]+$ ]] && { echo 'ERROR: unsafe directory path' >&2; exit 1; }
[[ ! "$PATTERN" =~ ^[A-Za-z0-9._-]+$ ]]    && { echo 'ERROR: unsafe pattern'        >&2; exit 1; }

#--- 2. Build command with an array ---
cmd=(find -- "$SEARCH_DIR" -type f -name "$PATTERN")

#--- 3. Execute — no string interpolation, no eval ---
echo "Executing: ${cmd[*]}"
"${cmd[@]}"

ตรวจสอบความรู้: การใส่เครื่องหมายอัญประกาศและการป้องกันการฉีดคำสั่ง

ทดสอบความเข้าใจแนวคิดสำคัญในบทเรียนนี้

ทบทวนบทเรียน: การป้องกันการฉีดคำสั่งและอาร์กิวเมนต์

คุณได้เรียนรู้ชุดเครื่องมือป้องกันอย่างครบถ้วนสำหรับการจัดการอินพุต Bash อย่างปลอดภัย:

  • การแยกคำ และ การขยายโกลบ เป็นกลไกพื้นฐานที่เปลี่ยนตัวแปรที่ไม่ปลอดภัยให้กลายเป็นช่องทางสำหรับการฉีดคำสั่ง
  • ใส่เครื่องหมายอัญประกาศคู่ให้ตัวแปรทุกตัว ("$var", "$@", "${arr[@]}") เพื่อระงับภัยคุกคามทั้งสองแบบ
  • ใช้ "$@" — อย่าใช้ $@ หรือ $* โดยไม่ใส่เครื่องหมายอัญประกาศ — เมื่อส่งต่ออาร์กิวเมนต์
  • เติม -- หน้าชื่อไฟล์ที่ผู้ใช้ระบุ เพื่อป้องกันการฉีดแฟล็ก
  • ใช้รายการอนุญาตกับอินพุตภายนอกทั้งหมด โดยมีตัวตรวจสอบนิพจน์ทั่วไป ([[ $v =~ ^pattern$ ]]) ก่อนที่อินพุตจะไปถึงคำสั่งใด ๆ
  • สร้างคำสั่งแบบไดนามิกด้วยอาร์เรย์ (cmd+=() → "${cmd[@]}") อย่าต่อสตริง
  • กำจัดการใช้ eval และ bash -c "$input" โดยใช้ ${!varname} สำหรับการขยายทางอ้อมที่ปลอดภัย
  • เปิดสคริปต์ด้วย set -euo pipefail และ IFS=$'\n\t' เสมอ เพื่อเป็นพื้นฐานที่เสริมความปลอดภัย

เมื่อใช้แนวปฏิบัติเหล่านี้อย่างสม่ำเสมอตั้งแต่บรรทัดแรกของทุกสคริปต์ จะลดพื้นที่โจมตีของ Bash สำหรับช่องโหว่ประเภทการฉีดคำสั่งได้จนเกือบเป็นศูนย์

คำถามที่พบบ่อย

บทเรียน “การป้องกันการแทรกคำสั่งและอาร์กิวเมนต์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การป้องกันการแทรกคำสั่งและอาร์กิวเมนต์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส DevOps Bootcamp ให้อัปเกรดเป็น CoddyKit PRO คอร์ส DevOps Bootcamp มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การป้องกันการแทรกคำสั่งและอาร์กิวเมนต์”

ใส่เครื่องหมายคำพูด ตรวจสอบ และส่งอินพุตที่ไม่น่าเชื่อถือผ่านอาร์เรย์ เพื่อกำจัดการแยกคำและการแทรกผ่าน eval คุณปฏิบัติ DevOps Bootcamp ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน DevOps Bootcamp หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน DevOps Bootcamp บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “การป้องกันการแทรกคำสั่งและอาร์กิวเมนต์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน DevOps Bootcamp นี้ได้ไหม

ได้ บทเรียน DevOps Bootcamp ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การป้องกันการแทรกคำสั่งและอาร์กิวเมนต์
  2. การจัดการความลับอย่างปลอดภัยและสุขอนามัยของสภาพแวดล้อม
  3. การทำงานด้วยสิทธิ์น้อยที่สุดและวินัยในการใช้ sudo
  4. การวิเคราะห์แบบสถิตและการตรวจสอบด้วย ShellCheck
← กลับไปที่ DevOps Bootcamp