จะหลีกเลี่ยงการใช้ sudo เมื่อทำงานใน / var / www ได้อย่างไร?


173

ฉันต้องการที่จะหยุดต้องใช้ทุกครั้งที่ผมทำงานในsudo /var/wwwฉันจะทำสิ่งนั้นได้อย่างไร ฉันแค่ต้องการที่จะนำเว็บไซต์ทั้งหมดของฉันไปไว้ในไดเรกทอรีนี้และทำงานกับพวกเขาโดยไม่เจ็บปวดมากเกินไป


3
คุณใช้อาปาเช่หรือไม่?
Rinzwind

1
หลังจากอ่านที่นี่สิ่งนี้ยังสามารถช่วยได้ในส่วนของการอนุญาต: askubuntu.com/questions/20105/…
Luis Alvarado

2
อีกวิธีในการรับความปลอดภัยคือการใช้งานต่อไปsudo -u www-dataแต่ จำกัด ตัวคุณเองในsudoersไฟล์ให้สามารถเท่านั้นsudo www-data(และไม่ใช่ sudo root) ดูserverfault.com/questions/295429/…
Simon Woodside

คำตอบ:


250

คำตอบส่วนใหญ่ที่นี่ไม่ได้เขียนโดยคำนึงถึงความปลอดภัย เป็นเรื่องดีที่ได้รับความรู้สึกว่าการวิ่งsudoในแต่ละครั้งนั้นไม่ฉลาด หากคุณพิมพ์ผิด (ตัวอย่างเช่นพื้นที่สีขาวเดียวในสถานที่ที่ไม่ถูกต้อง: sudo rm -rf / var/www/dir ห้ามดำเนินการ! ) คุณอาจทิ้งระบบของคุณ

หมายเหตุ:เริ่มต้นด้วย Apache 2.4.7 / Ubuntu 14.04, /var/wwwถูกย้ายไปที่/var/www/htmlปรับคำสั่งในคำตอบนี้ตามลำดับ

ดู:

ความคิดที่ไม่ดี:

  • chmod 777(sagarchalise) - อนุญาตให้ทุกคนที่มีสิทธิ์เข้าถึงระบบของคุณเขียนลงในไดเรกทอรีและไฟล์และทำให้ผู้บุกรุกสามารถรันโค้ดใด ๆ ภายใต้www-dataผู้ใช้
  • chgrp -R www-data $HOME(cob) - ใช้www-dataสำหรับอ่านหรือเขียนไฟล์ใด ๆ ในโฮมไดเร็กตอรี่ นี่ไม่ใช่การรักษากฎ Least Privilege ไว้ในใจ
  • chown -R $USER:$USER /var/www(kv1dr) - หากโลกไม่ได้รับอนุญาตให้อ่าน/var/wwwเว็บเซิร์ฟเวอร์ที่ทำงานภายใต้www-dataจะไม่สามารถอ่าน (ให้บริการ) ไฟล์ได้ หากไฟล์นั้นเป็นเอกสาร HTML ธรรมดาที่สาธารณชนเข้าถึงได้อาจเป็นปัญหาหากโลกไม่สามารถอ่านไฟล์ได้ แต่ถ้าไฟล์นั้นเป็นไฟล์ PHP ที่มีรหัสผ่านอยู่ก็เป็นได้

หมายเหตุ : ในโซลูชันด้านล่างฉันได้รับwww-dataสิทธิ์ในการเขียน อย่างไรก็ตาม/usr/share/doc/base-passwd/users-and-groups.txt.gzรัฐ:

www ข้อมูล

เว็บเซิร์ฟเวอร์บางตัวทำงานเป็น www-data เนื้อหาเว็บไม่ควรเป็นของผู้ใช้รายนี้หรือเว็บเซิร์ฟเวอร์ที่ถูกบุกรุกจะสามารถเขียนเว็บไซต์ใหม่ได้ ข้อมูลที่เขียนโดยเว็บเซิร์ฟเวอร์จะเป็นของ www-data

ที่เป็นไปไม่ได้ให้สิทธิ์ในการเขียนไปยังwww-dataกลุ่ม www-dataจำเป็นต้องสามารถอ่านไฟล์ได้เท่านั้นเพื่อให้เว็บเซิร์ฟเวอร์สามารถให้บริการได้ กรณีเดียวที่www-dataจำเป็นต้องมีสิทธิ์ในการเขียนสำหรับไดเรกทอรีที่จัดเก็บการอัปโหลดและตำแหน่งอื่น ๆ ที่จำเป็นต้องเขียน

โซลูชันที่ 1

เพิ่มตัวคุณเองลงในwww-dataกลุ่มและตั้งค่าบิตบิตบน/var/wwwไดเรกทอรีเพื่อให้ไฟล์ที่สร้างขึ้นใหม่ทั้งหมดสืบทอดกลุ่มนี้เช่นกัน

sudo gpasswd -a "$USER" www-data

แก้ไขไฟล์ที่สร้างไว้ก่อนหน้า (สมมติว่าคุณเป็นผู้ใช้คนเดียว/var/www):

sudo chown -R "$USER":www-data /var/www
find /var/www -type f -exec chmod 0660 {} \;
sudo find /var/www -type d -exec chmod 2770 {} \;

(ยิ่งปลอดภัยยิ่งขึ้น: ใช้งาน640หรือ2750ด้วยตนเองchmod g+w file-or-dirที่จำเป็นต้องเขียนโดยเว็บเซิร์ฟเวอร์)

โซลูชันที่ 2

สร้าง symlink สำหรับแต่ละโครงการในโฮมไดเร็กตอรี่ของคุณ สมมติว่าโครงการของคุณตั้งอยู่ที่~/projects/fooและคุณต้องการให้ตั้งอยู่ที่/var/www/fooรัน:

sudo ln -sT ~/projects/foo /var/www/foo

หากโฮมไดเร็กตอรี่ของคุณไม่มีการตั้งค่าบิตรันไทม์ (ลงมา) สำหรับother(เพื่อเหตุผลด้านความปลอดภัย), ให้เปลี่ยนกลุ่มของมันเป็นwww-data, แต่ตั้งค่าบิตรันไทม์เท่านั้น (ไม่อ่าน / เขียน). ทำเช่นเดียวกันกับ~/projectsโฟลเดอร์เนื่องจากอาจมีโครงการอื่นที่ไม่ใช่ www (คุณไม่ต้องการsudoหากคุณเพิ่มผู้ใช้ไปยังwww-dataกลุ่มก่อนหน้านี้)

sudo chgrp www-data ~ ~/projects
chmod 710 ~ ~/projects

ตั้งค่ากลุ่มเป็นwww-dataเปิด~/projects/fooและอนุญาตให้เว็บเซิร์ฟเวอร์อ่านและเขียนไฟล์และไฟล์ + ไดเรกทอรีและลงสู่ไดเรกทอรี:

sudo chgrp www-data ~/projects/foo
find ~/projects/foo -type f -exec chmod 660 {} \;
find ~/projects/foo -type d -exec chmod 2770 {} \;

ปลอดภัยยิ่งขึ้น: ใช้ 640 และ 2750 โดยค่าเริ่มต้นและ chmod ไฟล์และไดเรกทอรีด้วยตนเองที่ผู้ใช้เว็บเซิร์ฟเวอร์ต้องเขียนได้ ควรเพิ่ม setgid บิตเฉพาะเมื่อคุณต้องการให้ทุกไฟล์ที่สร้างขึ้นใหม่~/projects/fooสามารถเข้าถึงได้โดยกลุ่ม

จากนี้ไปคุณจะสามารถเข้าถึงเว็บไซต์ของคุณที่และแก้ไขไฟล์ในโครงการของคุณhttp://localhost/foo~/projects/foo

ดูสิ่งนี้ด้วย


คุณคิดอย่างไรเกี่ยวกับ www-session ใน terminal โดยsudo su www-data? รวมกับพรอมต์ที่มีสีต่างกันเพื่อทำให้ชัดเจนมากขึ้นว่าเป็นเปลือกของผู้ใช้ที่แตกต่างกันและนโยบายจะวาง xterm ที่สอดคล้องกันเสมอ - ตัวอย่างเช่นเดสก์ท็อปเสมือน 4 เพื่อให้คุณคุ้นเคย หลีกเลี่ยงความสับสน?
ผู้ใช้ที่ไม่รู้จัก

@ ผู้ใช้ที่ไม่รู้จัก: หากคุณทำทุกอย่างในเครื่องเทอร์มินัลเพราะคุณแยกบัญชีผู้ใช้ได้ชัดเจน แต่มันจะไม่ทำงานถ้าคุณใช้โปรแกรม GUI geditเช่น ฉันไม่เคยค้นคว้าว่าการรันโปรแกรม GUI ภายใต้ผู้ใช้รายอื่นในเซสชันปัจจุบันนั้นปลอดภัยหรือไม่มันจะเป็นคำถามที่น่าสนใจ
Lekensteyn

1
@imaginaryRobots: ถ้าฉันจะโพสต์โซลูชั่นที่แตกต่างกันสำหรับทุกคำถาม Askubuntu จะเต็มไปด้วยคำตอบของสามบรรทัด ฉันจะเก็บไว้ตามที่เป็นถ้าคุณไม่สามารถโน้มน้าวให้ฉันแยกมัน
Lekensteyn

1
@berbt setfacl -d u::rwX,g::rX /var/wwwมีเอฟเฟกต์ตลกที่โหมดเริ่มต้นจะเป็น 0750 (หรือ 0640) แม้ว่า umask จะเป็นศูนย์ มันอาจเป็นความคิดที่ดีถ้าคุณต้องการหลีกเลี่ยงไฟล์ที่เขียนได้ทั่วโลก แต่ถ้าหากโลก/var/wwwนี้ไม่สามารถเข้าถึงได้โดยที่ไม่สามารถเข้าถึงได้
Lekensteyn

1
มีปัญหาในการแปลงกลับกระบวนการในโซลูชันที่ 1 หรือไม่? โดยที่ฉันหมายถึง/var/www/app01มีความเป็นเจ้าของapp01:app01แล้วwww-data ผู้ใช้จะถูกเพิ่มในapp01 กลุ่มหรือไม่ หรือว่าจะทำลายบางสิ่งบางอย่าง?
Jack_Hu

9

แทนที่จะจัดเก็บเว็บไซต์ของฉันใน / var / www ฉันวางลิงค์ไว้ที่เว็บไซต์ที่อยู่ในโฟลเดอร์หลักของฉัน ฉันสามารถแก้ไขหรือเพิ่มหน้าในเว็บไซต์ของฉันได้อย่างอิสระ เมื่อฉันมีความสุขกับการเปลี่ยนแปลงฉันก็ FTP ไปยัง บริษัท โฮสติ้งที่ชื่อโดเมนของฉันเชื่อมโยง


นี่เป็นความคิดที่สมเหตุสมผล
thomasrutter

7

หากคุณสร้าง / var / www เขียนโดยกลุ่มและเพิ่มตัวเองในกลุ่มคุณจะไม่ต้องใช้ sudo ในขณะที่ยังปลอดภัยอยู่ ลองสิ่งนี้:

sudo adduser <username> www-data
sudo chown -R www-data:www-data /var/www
sudo chmod -R g+rw /var/www

คุณควรจะสามารถแก้ไข/var/www/ไฟล์ได้โดยไม่ต้องยุ่งยาก

บรรทัดแรกจะเพิ่มคุณในwww-dataกลุ่มบรรทัดที่สองจะล้างไฟล์ใด ๆ ที่มีความเป็นเจ้าของสับสนและบรรทัดที่สามจะทำให้ผู้ใช้ทุกคนที่เป็นสมาชิกของwww-dataกลุ่มสามารถอ่านและเขียนไฟล์ทั้งหมด/var/wwwได้


4
นี่เป็นแนวคิดที่ไม่ดีมากสำหรับการรักษาความปลอดภัยและไม่ควรทำตามคำแนะนำนี้ด้วยเหตุผลที่อธิบายไว้ในคำตอบอื่น ๆ www-ข้อมูลที่ควรจะเป็นด้อยโอกาสกลุ่มโดยไม่ต้องเขียนเข้าถึง
thomasrutter

5

Don'ts

  • อย่าตั้งค่าการอนุญาตของไฟล์เป็น777 (เขียนได้ทั่วโลก)

    นี่เป็นข้อบกพร่องด้านความปลอดภัยที่สำคัญโดยเฉพาะถ้าคุณเปิดใช้งานสคริปต์ฝั่งเซิร์ฟเวอร์เช่น PHP กระบวนการที่ไม่ได้รับสิทธิพิเศษไม่ควรเขียนลงไฟล์ที่จะส่งผลกระทบต่อเว็บไซต์หรือในกรณีของการใช้สคริปต์ฝั่งเซิร์ฟเวอร์ให้ใช้รหัสโดยอำเภอใจ

  • อย่าเพิ่มตัวเองในฐานะสมาชิกของกลุ่มwww-dataและให้สิทธิ์ในการเขียน

    วัตถุประสงค์ของกลุ่มนั้นก็คือว่ามันเป็นด้อยโอกาสกลุ่มว่ากระบวนการเซิร์ฟเวอร์ทำงานเป็น พวกเขาควรมีสิทธิ์เข้าถึงเพื่ออ่านไฟล์เว็บไซต์เท่าที่จะทำได้ด้วยเหตุผลเดียวกับที่กล่าวมาข้างต้น

  • อย่าเปลี่ยนสิทธิ์ของกระบวนการ Apache

    กระบวนการลูก Apache เรียกใช้ในฐานะwww-dataผู้ใช้และกลุ่มโดยค่าเริ่มต้นและสิ่งนี้ไม่ควรเปลี่ยนแปลง นี่เป็นเพียงวิธีหนึ่งเดียวในการให้พวกเขาไม่ได้รับอนุญาตให้เขียนระบบไฟล์

    ในบางสถานการณ์คุณต้องการให้สคริปต์ฝั่งเซิร์ฟเวอร์ของคุณสามารถเขียนลงไฟล์ได้ซึ่งในกรณีนี้ควรเขียนไฟล์เหล่านั้นเท่านั้นwww-dataและต้องมีการดูแลเพื่อความปลอดภัย

Dos

  • ตั้งค่าไฟล์ให้เป็นของคุณเอง

    หากคุณเป็นเพียงคนเดียวหรือเป็นคนธรรมดาที่จะแก้ไขไฟล์บางไฟล์ในเว็บไซต์ก็เป็นเรื่องที่สมควรอย่างยิ่งที่คุณจะต้องเป็นเจ้าของไฟล์เหล่านั้น <your username>ตั้งเจ้าของของพวกเขาไป

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

  • เลือกสถานที่ที่เหมาะสมในการจัดเก็บไฟล์ (โดยใช้DocumentRoot )

    หาก/var/wwwไม่เหมาะสมคุณสามารถนำไปวางไว้ที่อื่นได้ หากพวกเขามีเฉพาะการพัฒนาหรือการทดสอบของคุณเองคุณสามารถวางไว้ในไดเรกทอรีบ้านของคุณ /srvหรือคุณสามารถตั้งค่าบางอย่างในไดเรกทอรี

  • หากคุณต้องการให้สิทธิ์การเขียนเป็นกลุ่มให้สร้างกลุ่มใหม่เพื่อวัตถุประสงค์

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


5

มันง่ายมาก คุณไม่จำเป็นต้องเปิดใช้งาน apache 'UserDir' (ไม่แนะนำให้ใช้) หรือทำกับกลุ่ม 'www-data' (apache group ในกรณีบน Fedora)

เพียงแค่สร้างไดเรกทอรีโครงการของคุณภายใน /var/www/html

cd /var/www/html
sudo mkdir my_project

จากนั้นเพียงแค่สร้างไดเรกทอรีโครงการให้กับผู้ใช้ของคุณ

sudo chown your_username my_project

ตอนนี้คุณสามารถเริ่มทำงานกับโฟลเดอร์โปรเจ็กต์ของคุณในฐานะผู้ใช้ปกติด้วยตัวแก้ไข IDE ที่คุณต้องการ ไม่มีรายละเอียดเพิ่มเติมsudos :)


1
+1 นั่นคือสิ่งที่ฉันทำ: เปลี่ยนความเป็นเจ้าของไม่ใช่ของ/var/wwwตัวเอง แต่เป็นของไดเรกทอรีย่อย
fkraiem

2

chmod in / var on www เพื่ออนุญาตให้เจ้าของเข้าถึงและ chown เพื่อให้แน่ใจว่าคุณเป็นเจ้าของ อาจเป็นความคิดที่โง่ แต่มันก็ใช้ได้ผลแน่นอน


2
ไม่ใช่ความคิดที่งี่เง่ามันเป็นความคิดที่ปลอดภัย หมายเหตุ: คุณไม่จำเป็นต้อง (และไม่ควร) เปลี่ยนการอนุญาตของ/varเพียง/var/wwwและ / หรือเนื้อหา
thomasrutter

1

คุณสามารถเริ่ม www-session ใน terminal โดย

sudo su www-data

เมื่อรวมกับพรอมต์ที่มีสีต่างกัน * เพื่อให้ชัดเจนยิ่งขึ้นว่าเป็นเปลือกของผู้ใช้ที่แตกต่างกันและนโยบายมักจะวาง xterm ที่สอดคล้องกัน (และตัวแก้ไขและอื่น ๆ ) บน - ตัวอย่าง - virtual desktop 4 ดังนั้น คุณคุ้นเคยกับมันเพื่อหลีกเลี่ยงความสับสน

*) สำหรับพรอมต์สีที่แตกต่างพร้อมตัวอักษร differnt ให้สร้างไฟล์ / etc / prompt เช่นนี้:

# PROMPTING
#       When  executing  interactively, bash displays the primary prompt PS1 when it is ready to read a command, and the sec-
#       ondary prompt PS2 when it needs more input to complete a command.  Bash allows these prompt strings to be  customized
#       by inserting a number of backslash-escaped special characters that are decoded as follows:
#              \a     an ASCII bell character (07)
#              \d     the date in "Weekday Month Date" format (e.g., "Tue May 26")
#              \D{format}
#                     the  format is passed to strftime(3) and the result is inserted into the prompt string; an empty format
#                     results in a locale-specific time representation.  The braces are required
#              \e     an ASCII escape character (033)
#              \h     the hostname up to the first `.'
#              \H     the hostname
#              \j     the number of jobs currently managed by the shell
#              \l     the basename of the shell's terminal device name
#              \n     newline
#              \r     carriage return
#              \s     the name of the shell, the basename of $0 (the portion following the final slash)
#              \t     the current time in 24-hour HH:MM:SS format
#              \T     the current time in 12-hour HH:MM:SS format
#              \@     the current time in 12-hour am/pm format
#              \A     the current time in 24-hour HH:MM format
#              \u     the username of the current user
#              \v     the version of bash (e.g., 2.00)
#              \V     the release of bash, version + patchelvel (e.g., 2.00.0)
#              \w     the current working directory
#              \W     the basename of the current working directory
#              \!     the history number of this command
#              \#     the command number of this command
#              \$     if the effective UID is 0, a #, otherwise a $
#              \nnn   the character corresponding to the octal number nnn
#              \\     a backslash
#              \[     begin a sequence of non-printing characters, which could be used to embed a terminal  control  sequence
#                     into the prompt
#              \]     end a sequence of non-printing characters
#
#       The  command  number and the history number are usually different: the history number of a command is its position in
#       the history list, which may include commands restored from the history file (see HISTORY below),  while  the  command
#       number  is  the  position in the sequence of commands executed during the current shell session.  After the string is
#
# colors:
# \[...\]   wird benötigt, damit die shell weiß, daß hier kein printable output ist, und die Umbrüche richtig plaziert.
#
# ANSI COLORS
CRE="\[
[K\]"
NORMAL="\[[0;39m\]"
# RED: Failure or error message
RED="\[[1;31m\]"
# GREEN: Success message
GREEN="\[[1;32m\]"
# YELLOW: Descriptions
YELLOW="\[[1;33m\]"
# BLUE: System messages
BLUE="\[[1;34m\]"
# MAGENTA: Found devices or drivers
MAGENTA="\[[1;35m\]"
# CYAN: Questions
CYAN="\[[1;36m\]"
# BOLD WHITE: Hint
WHITE="\[[1;37m\]"
#
# default:
# postgres, oracle, www-data
#
# PS1=$BLUE"machine]->"$NORMAL\\w"$BLUE ø $NORMAL"
PS1=$BLUE"machine]:"$NORMAL\\w"$BLUE > $NORMAL"
#
# root, stefan:
#
case "$UID" in
    '0')
        PS1=$RED"machine:"$NORMAL\\w"$RED # $NORMAL"
    ;;
    '1000')
    PS1=$GREEN"machine:"$BLUE\\w$YELLOW" > "$NORMAL
    ;;
#    default)
#    ;;
esac

และแหล่งที่มาจาก/etc/bash.bashrcตัวอย่างเช่น

เป็นเครื่องมือเพิ่มเติมที่ช่วยแยกความแตกต่างคุณสามารถแก้ไขไฟล์ด้วยนามแฝง 'แก้ไข' หรือ symlink ซึ่งชี้ขึ้นอยู่กับตัวตนของคุณ (เทย์เลอร์ / www-data) เป็น gedit หรือ mousepad, vim หรือ pico หรือคุณสามารถใช้ส่วนกำหนดค่าตัวแก้ไขที่แตกต่างกันอย่างน้อยก็ใน gedit คุณสามารถตั้งค่าของคุณเป็นข้อความสีดำบนพื้นสีขาวหรือข้อความสีขาวบนพื้นสีดำ

ฉันมีนโยบายดังกล่าวสำหรับการทำงานในฐานะรูทเท่านั้นดังนั้นฉันจึงไม่แน่ใจว่าจะทำงานได้ดีกับข้อมูล www เมื่อรวมกับ ssh-เซสชันเพื่อโฮสต์ differnt ซึ่งมีการแจ้งเตือนของตัวเองมันก็ไม่ได้หยุดฉันจากการผิดปกติ แต่ถ้ามันเกิดขึ้นฉันก็รู้ได้อย่างรวดเร็วว่ามีอะไรผิดปกติและมันเกิดขึ้นน้อยมาก

หมายเหตุ: พรอมต์สคริปต์เป็นส่วนหนึ่งของ manpage of bash


สิ่งนี้จะได้ผลและจะไม่ (หากใช้อย่างระมัดระวัง) ส่งผลเสียต่อความปลอดภัย แต่อาจไม่ใช่วิธีแก้ปัญหาที่ตรงไปตรงมาที่สุด มันเป็นทางออกที่ถูกต้องสำหรับบางคน
thomasrutter
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.