अनुशंसित निर्देशिका अनुमतियाँ क्या हैं?


145

मैं एक ड्रुपल 7 साइट को तैनात करने के लिए तैयार हूं और मुझे इस बारे में कोई दस्तावेज नहीं मिल सकता है कि अनुशंसित सुरक्षा-सचेत फ़ाइल और निर्देशिका अनुमतियाँ किस पर सेट होनी चाहिए।

विशेष रूप से default/files/(उप निर्देशिकाएं भी?) settings.php, .htaccessऔर कुछ भी जो मुझे पता होना चाहिए।


1
यहाँ एक उत्तर भी है: drupal.stackexchange.com/questions/52695/…
फ्री रेडिकल

एक ब्लॉग है जो इसे खूबसूरती से समझाता है और इसके हर पहलू को एक सार तरीके से शामिल करता है। technologymythbuster.blogspot.com/2018/06/…
कल्पेश पोपट

जवाबों:


69

आपका वेब सर्वर सभी फ़ाइलों को पढ़ने में सक्षम होना चाहिए, लेकिन उन्हें लिखना नहीं चाहिए। यदि आपकी साइट में फ़ाइलें अपलोड करना शामिल है, तो सर्वर को केवल उस एक फ़ोल्डर में लिखने की अनुमति दें।

यह निर्धारित करने के बारे में अधिक जानकारी, साथ ही साथ कुछ चीजें जो आपके नहीं होने पर हो सकती हैं, ड्रुपल डॉक्स में उपलब्ध हैं ।


13
यह उन साइटों / डिफ़ॉल्ट / फ़ाइलों की निर्देशिका के बारे में सही नहीं है, जो वेब सर्वर द्वारा लिखने योग्य होनी चाहिए या आपके पास परेशानियों का सामना करना पड़ेगा।
रॉबी

3
@rooby दूसरा वाक्य स्पष्ट करता है कि।
kenorb

14
हालांकि यह कहता है कि "यदि आपकी साइट में फ़ाइलें अपलोड करना शामिल है" लेकिन वह एकमात्र कारण नहीं है जिसके लिए आपको फ़ाइल निर्देशिका तक पहुंच लिखने की आवश्यकता हो सकती है। एक बहुत ही सामान्य उदाहरण है js / css एकत्रीकरण, जो असंबंधित उपयोगकर्ताओं को फाइलें अपलोड कर रहा है। अन्य मॉड्यूल भी उस निर्देशिका को लिखने योग्य होने की उम्मीद कर सकते हैं।
रॉबी

91

यही कारण है कि Drupal इतने सारे की तरह पेज बहुत लंबा और भ्रामक है। लेकिन इसमें जेसन की यह पोस्ट शामिल है, जिसने सिर पर कील ठोक दी:

1 नवंबर, 2010 को दोपहर 12:40 बजे जेसन सेल द्वारा पोस्ट किया गया

यह और सब कुछ लिखने के लिए धन्यवाद, लेकिन यह सब और मैं और इस पृष्ठ को पढ़ने वाले 99% लोग वास्तव में चाहते हैं कि फ़ोल्डरों की सूची के आगे संख्याओं की एक सूची है।

  • /default 755 पर
  • /default/files 744 (या 755) पर सभी सबफ़ोल्डर्स और फाइलें शामिल हैं
  • /default/themes 755 पर सभी सबफ़ोल्डर्स और फ़ाइलों को शामिल करें
  • /default/modules 755 पर सभी सबफ़ोल्डर्स और फ़ाइलों को शामिल करें
  • /default/settings.phpऔर /default/default.settings.php444 पर

7
विषय लंबा और भ्रमित करने वाला है। पेज स्थिति की वास्तविकता को फिट करता है।
greggles

17
... द्रुपाल डॉक्स का! और इसीलिए इसे तुरंत कुछ सरल और समझ में बदलने की आवश्यकता है! खासकर जब सुरक्षा की बात हो। बस सुरक्षा के बारे में बात कर रहे हैं! क्योंकि यह हम सभी का है। एक संक्रमित सर्वर न केवल अनुभवहीन Drupal उपयोगकर्ता की समस्या है। यह हम सभी की समस्या है। इसलिए यह डेवलपर्स के लिए जटिल और बुरी तरह से लिखे गए डॉक्स को जटिलता और गहनता दिखाने के लिए प्रेरित करने और उन्हें अपने आप को संभालने के लिए कितना अच्छा है, इसे बनाए रखने के लिए बहुत उपयोगी नहीं है। मुझे एक साधारण फ़ाइल अनुमतियाँ ट्री ग्राफ़िक छोड़ने की बात नहीं दिखती है। वेबिक उस पर सहमत हैं।
nilsun

3
755 / डिफ़ॉल्ट / फ़ाइलों पर क्यों है? क्या यह हमेशा 744 नहीं होना चाहिए, जब कोई सामने वाले को हैक करके (या खराब कॉन्फ़िगरेशन के माध्यम से) कुछ दुर्भावनापूर्ण अपलोड करने का प्रबंधन करता है? क्या 755 होने का कोई कारण है? क्या / tmp के बारे में?
वेबड्रिप्स

1
Settings.php फ़ाइल 440 होनी चाहिए। "अन्य" Settings.php को देखने में सक्षम नहीं होना चाहिए। 740 यदि आप सूडो कमांड्स के बिना इसे लिखना चाहते हैं।
ब्रायडन

बस उत्सुक क्यों। फाइल और tmp फ़ोल्डर में .acaccess फाइल को वेबसर्वर द्वारा लिखने की आवश्यकता है? यह सेटिंग .php के रूप में इसे 444 चिह्नित करना सुरक्षित नहीं है। कारण मैं पूछ रहा हूँ कि क्या junkfile.php को हैकर द्वारा वेबसर्वर के माध्यम से फाइल फोल्डर में अपलोड किया जा सकता है ।htaccess फाइल को बदला जा सकता है। क्या मैं सही हू?
किरकिंग

82

एक सर्वर पर एक नई Drupal साइट बनाने के लिए मेरा अभ्यास एक उपयोगकर्ता है जो वेब सर्वर (आमतौर पर Apache) समूह का एक हिस्सा है, और उस उपयोगकर्ता के पास सभी Drupal फाइलें हैं। उबंटू पर, ये सेट करने के लिए आदेश हैं:

# Create a new example user, setting up /var/www/example as their home dir.
useradd -s /bin/bash -d /var/www/example -m example

# Now add that user to the Apache group. On Ubuntu/Debian this group is usually
# called www-data, on CentOS it's usually apache.
usermod -a -G www-data example

# Set up a password for this user.
passwd example

एक बार जब मैंने वह सेट कर लिया है, तो मैं उस उपयोगकर्ता के रूप में लॉग इन करूँगा और Drupal को / var / www / example / docroot या समान पर स्थापित करूँगा, और फिर फाइल डायरेक्टरी को हाथ से बनाकर settings.php फ़ाइल पर कॉपी करूँगा। चूंकि हम Drupal में कॉपी करने से पहले हमारे उदाहरण के उपयोगकर्ता के रूप में लॉग इन करते हैं, इसलिए हमारी फ़ाइल स्वामित्व और अनुमतियां स्वचालित रूप से सभी कोर Drupal फ़ाइलों और स्क्रिप्ट (.htaccess फ़ाइलों सहित) पर ठीक से कॉन्फ़िगर होनी चाहिए।

su - example
cd docroot
cp sites/default/default.settings.php sites/default/settings.php

# Temporarily give the web server write permissions to settings.php
chgrp www-data sites/default/settings.php
chmod g+w sites/default/settings.php

अब फाइल डायरेक्टरी सेट करते हैं।

# Create the directory.
mkdir sites/default/files

# Now set the group to the Apache group. -R means recursive, and -v means 
# verbose mode.
chgrp -Rv www-data sites/default/files

इसके बाद हम अनुमतियाँ सेट करेंगे ताकि वेब सर्वर हमेशा इस निर्देशिका में मौजूद किसी भी फ़ाइल को लिख सके। हम अपने chmod कमांड में 2775 का उपयोग करके ऐसा करते हैं। 2 का मतलब है कि इस निर्देशिका में बनाई गई किसी भी नई फ़ाइल के लिए समूह आईडी को संरक्षित किया जाएगा। इसका मतलब यह है कि www - डेटा हमेशा किसी भी फाइल पर समूह होगा, जिससे वेब सर्वर और उपयोगकर्ता दोनों को हमेशा इस निर्देशिका में रखी गई किसी भी नई फाइल के लिए लिखने की अनुमति होगी। पहले 7 का मतलब है कि मालिक (उदाहरण) आर (पढ़ें) डब्ल्यू (लिखें) और एक्स (एक्सक्यूट) किसी भी फाइल को यहां कर सकते हैं। दूसरे 7 का मतलब है कि समूह (www-data) भी इस निर्देशिका में किसी भी फाइल को RW और X कर सकता है। अंत में, 5 का मतलब है कि अन्य उपयोगकर्ता आर और एक्स फाइल कर सकते हैं, लेकिन लिख नहीं सकते हैं।

 chmod 2775 sites/default/files

यदि इस निर्देशिका में कोई मौजूदा फ़ाइल है, तो सुनिश्चित करें कि वेब सर्वर ने उन पर परमिट लिखा है।

 chmod g+w -R sites/default/files

अब ड्रुपल स्थापित होने के लिए तैयार है। जब समाप्त हो जाए, तो settings.php पर वापस आना बहुत महत्वपूर्ण है और यह सुनिश्चित करें कि सभी उपयोगकर्ता केवल अनुमतियाँ पढ़ें।

 chmod 444 sites/default/settings.php

बस! यह सेट अप आपको किसी भी स्थिति से बचने के लिए सुनिश्चित करता है, जहां निर्देशिका या वेब सर्वर का मालिक उपयोगकर्ता फ़ाइलों को निर्देशिका में फ़ाइलों को लिख / बदल / हटा नहीं सकता है।


यह सेटिंग के लिए सुरक्षित नहीं है। वैसे भी वह फाइल ड्रूपल कोर में शायद ही अपडेट की जाती है।
किरकिंग

आप .htaccess को 444 पर सेट कर सकते हैं, लेकिन यह Drupal Core को अपग्रेड करते समय अतिरिक्त सिरदर्द जोड़ देगा और आपकी साइट को और अधिक सुरक्षित नहीं बना देगा।
q0rban

30

Drupal फ़ाइलें फ़ोल्डर को वेबसर्वर द्वारा लिखने योग्य होना चाहिए। ऐसा करने का सबसे सुरक्षित तरीका समूह को बदलना है और इसे समूह योग्य बनाना है, जैसे:

chgrp www-data sites/default/files
chmod g+w sites/default/files

फाइल अपलोड फोल्डर एक तरफ, सभी फाइलों के लिए सबसे सुरक्षित 644 है, निर्देशिकाओं के लिए 755।

इसे इस तरह पूरा किया जा सकता है (जब Drupal-site फ़ोल्डर में चलाया .जाता है, वर्तमान पथ के लिए है):

find . -type f | xargs chmod 644
find . -type d | xargs chmod 755

याद रखें कि chmod g+wउपरोक्त कमांड को चलाने के बाद आपको फिर से सेट करना होगा, क्योंकि वे सभी फाइलों और फ़ोल्डरों पर चामोड को रीसेट कर देंगे।


2
यह उत्तर मानता है: आप ubuntu पर हैं। आपकी साइट केवल उसी सर्वर पर चल रही है। यह समस्या को स्वतः हल करने के बजाय एक बार हल करता है (जैसे umask बदलकर)।
greggles

जरूरी नहीं कि उबंटू हो, और यह अभी भी एक उपयोगी उपाय है, भले ही एक ही सर्वर पर कई साइटें चल रही हों। ओम्स्क को बदलना (जो उम्मीद है कि पहले से ही इन सेटिंग्स हैं) कुछ ऐसा नहीं है जो मैं लोगों को लिनक्स में अच्छी तरह से वाकिफ नहीं होने की सलाह दूंगा। मुझे पता है कि यह सही सुरक्षा नहीं है, लेकिन चलो यहाँ अच्छे के दुश्मन नहीं हैं।
मिकाल

एक मल्टीसाइट पर मैं चलता हूं chgrp -R www-data sites/*/filesऔर chmod -R g+w sites/*/filesस्थिति पृष्ठ की त्रुटियों से छुटकारा पाने के लिए।
लेमनक्स

20

"Chmod blah" या "chown X" के लिए कोई भी सलाह बिना यह जानने के लिए व्यर्थ है: डिफ़ॉल्ट उपयोगकर्ता क्या है: समूह फ़ाइलों पर है और उपयोगकर्ता और आपके वेबसर्वर के रूप में कौन सा समूह चलाता है।

ड्रुपल डॉक्स अन्य लोगों से जुड़े हुए हैं जो विषय पर काफी अच्छे हैं, लेकिन एक अन्य संसाधन सुरक्षा समीक्षा मॉड्यूल है जो यह सुनिश्चित करने में मदद करता है कि आपने सब कुछ ठीक से सेट कर लिया है।


9

मैं इस मामले पर विचार करूंगा कि एफ़टीपी का उपयोग करने वाले सर्वर पर फाइलें बनाई गई हैं, जो कि वेब सर्वर रन (सामान्य रूप से, अपाचे कोई नहीं / कोई नहीं के रूप में) से भिन्न क्रेडेंशियल्स का उपयोग करके। इसका मतलब यह है कि उपयोगकर्ता जो ड्रुपल इंस्टॉलर चलाने से पहले मैन्युअल रूप से बनाई गई फ़ाइलों का मालिक है (जिसमें ड्रुपल आर्काइव से सर्वर पर अपलोड की गई फाइलें भी शामिल हैं) वह वेब सर्वर चलाने के लिए उपयोग किया जाने वाला उपयोगकर्ता नहीं है (न ही उपयोगकर्ता नाम या समूह से मेल खाता है) । यह परिदृश्य उस स्थिति पर भी लागू होता है जहां उन फ़ाइलों को SSH का उपयोग करके बनाया जाता है।

  • Settings.php फ़ाइल को Drupal इंस्टॉलर से लिखने योग्य होना चाहिए, लेकिन एक बार इंस्टॉलेशन होने के बाद इसे केवल पढ़ने के लिए बनाने का सुझाव दिया जाता है (इंस्टॉलर सुझाव देता है, और Drupal समय-समय पर जांच करेगा कि क्या फ़ाइल वास्तव में केवल-पढ़ने के लिए है)। मैं जिस परिदृश्य का वर्णन कर रहा हूं, उसमें इस फ़ाइल की अनुमति कम से कम 644 होनी चाहिए।
  • .Htaccess फ़ाइलें (जो कम से कम दो स्थानों पर मौजूद हैं) की अनुमति 644 होनी चाहिए। फ़ाइल बनाने वाले उपयोगकर्ता को अभी भी फ़ाइल को अधिलेखित करने में सक्षम होना चाहिए, मामले में Drupal का अगला संस्करण एक .htac फ़ाइल के साथ आता है। अद्यतन किया गया है (यह पहले से ही एक बार हुआ था, जब इसे सुरक्षा समस्या से बचने के लिए उस फ़ाइल में एक पंक्ति जोड़ा गया है)। अनुमतियों को 444 पर सेट करना भी संभव है, लेकिन उस स्थिति में, जब फ़ाइल को अपडेट करने की आवश्यकता होती है, तो अनुमतियों को वापस 644 में बदल दिया जाना चाहिए।
  • मॉड्यूल ( default/filesनिर्देशिका) द्वारा बनाई गई फ़ाइलों वाली निर्देशिका (उस उपयोगकर्ता के लिए होनी चाहिए जो वेब सर्वर प्रक्रियाओं को सौंपा गया है, जो तब उस वेब सर्वर पर चलने वाली PHP स्क्रिप्ट को सौंपा गया उपयोगकर्ता है):
    • पठनीय
    • लिखने योग्य
    • ट्रैवर्सेबल (मॉड्यूल तक पहुंचने में सक्षम होना चाहिए default/files/<directory-used-by-the-module>/<sub-directory-used-by-the-module>)

पर धागा पढ़ने के बाद drupal.org/node/244924 और विशेष रूप से drupal.org/node/244924#comment-8186447 प्रदान की कैसे फ़ाइलों को प्राप्त करने के विभिन्न तरीकों में से कोई भी संबंध के लिए अपलोड किया जा रहा केवल 660 आरडब्ल्यू आरडब्ल्यू ---- अर्थात्। निष्पादन के बिना बिट। क्या यह मुख्य सुरक्षा मुद्दा नहीं है?
किरकिंग

8

अनुशंसित फ़ाइल / निर्देशिका अनुमतियाँ:

  • Drupal webroot विश्व में पढ़ने योग्य होना चाहिए (देखें: updater.inc ): 0755
  • सार्वजनिक अपलोड निर्देशिकाओं के लिए: 0755 या 0775
  • निजी अपलोड निर्देशिकाओं के लिए: 0750 या 0770
  • सार्वजनिक अपलोड की गई फ़ाइलों के लिए: 0644 या 0664
  • निजी अपलोड की गई फ़ाइलों के लिए: 0640 या 0660
  • अपलोड निर्देशिका के भीतर .htaccess के लिए (देखें: file_create_htaccess () ): 0444 (डिफ़ॉल्ट) या 0644
  • सेटिंग्स के लिए। केवल पढ़ने के लिए सभी (और अन्य गोपनीय फ़ाइलों के लिए): 0440
  • अन्य सभी वेब निर्देशिकाओं के लिए: 0755
  • अन्य सभी वेब फ़ाइलों के लिए: 0644

अनुशंसित फ़ाइल / निर्देशिका स्वामित्व:

  • सभी अपलोड निर्देशिकाओं / फाइलों के मालिक को Apache उपयोगकर्ता के लिए सेट किया जाना चाहिए,
  • सभी वेब / स्रोत निर्देशिकाओं / फ़ाइलों के स्वामी को गैर-अपाचे उपयोगकर्ता के लिए सेट किया जाना चाहिए,
  • (वैकल्पिक रूप से) सभी स्रोतों का समूह अपाचे समूह के लिए सेट किया जाना चाहिए,

यहां वे चर हैं जो नई वस्तुओं के लिए डिफ़ॉल्ट dir / फ़ाइल अनुमतियों को नियंत्रित करते हैं:

file_chmod_directory: 0775
file_chmod_file: 0664

अनुमतियाँ ठीक करने के लिए कुछ स्क्रिप्ट यहाँ दी गई है: fix-permissions.sh


अधिक पढ़ें:


यहाँ वह स्क्रिप्ट है जिसका उपयोग मैं सार्वजनिक / निजी निर्देशिका के लिए दूरस्थ होस्ट पर अनुमतियाँ तय करने के लिए कर रहा हूँ:

#!/bin/sh -e
# Script to correct public/private directory and files permissions.
[ -z "$1" ] && { echo Usage: $0 @remote.dst; exit 1; }

DST="$1" && shift
GET_HTTP_GROUP='ps axo user,group,comm | egrep "(apache|httpd)" | grep -v ^root | uniq | cut -d\  -f 1'

drush $* $DST ssh 'PUB=$(drush dd %files) && PRIV=$(drush dd %private) && AGROUP=$('"$GET_HTTP_GROUP"') && chgrp -vR $AGROUP $PUB $PRIV && chmod -vR u+rwX,g+rwX,o+rX $PUB $PRIV'

नोट: उपरोक्त कोड अपाचे समूह को पुनः प्राप्त करने और इसे GET_HTTP_GROUPचर पर सेट करने का प्रयास करेगा ।


बहुत अच्छा धोखा-पत्र, बुकमार्क। अच्छी नौकरी ..
16:14

4

यह शेल स्क्रिप्ट इस पृष्ठ के नीचे पाया जाता है: https://www.drupal.org/node/244924

मैं इसे कभी-कभी यह सुनिश्चित करने के लिए चलाता हूं कि मेरी अनुमतियां सही तरीके से सेट की गई हैं।

#!/bin/bash
# Help menu
print_help() {
cat <<-HELP
This script is used to fix permissions of a Drupal installation
you need to provide the following arguments:
1) Path to your Drupal installation.
2) Username of the user that you want to give files/directories ownership.
3) HTTPD group name (defaults to www-data for Apache).
Usage: (sudo) bash ${0##*/} --drupal_path=PATH --drupal_user=USER --httpd_group=GROUP
Example: (sudo) bash ${0##*/} --drupal_path=/usr/local/apache2/htdocs --drupal_user=john --httpd_group=www-data
HELP
exit 0
}
if [ $(id -u) != 0 ]; then
  printf "**************************************\n"
  printf "* Error: You must run this with sudo. *\n"
  printf "**************************************\n"
  print_help
  exit 1
fi
drupal_path=${1%/}
drupal_user=${2}
httpd_group="${3:-www-data}"
# Parse Command Line Arguments
while [ $# -gt 0 ]; do
  case "$1" in
    --drupal_path=*)
      drupal_path="${1#*=}"
      ;;
    --drupal_user=*)
      drupal_user="${1#*=}"
      ;;
    --httpd_group=*)
      httpd_group="${1#*=}"
      ;;
    --help) print_help;;
    *)
      printf "***********************************************************\n"
      printf "* Error: Invalid argument, run --help for valid arguments. *\n"
      printf "***********************************************************\n"
      exit 1
  esac
  shift
done
if [ -z "${drupal_path}" ] || [ ! -d "${drupal_path}/sites" ] || [ ! -f "${drupal_path}/core/modules/system/system.module" ] && [ ! -f "${drupal_path}/modules/system/system.module" ]; then
  printf "*********************************************\n"
  printf "* Error: Please provide a valid Drupal path. *\n"
  printf "*********************************************\n"
  print_help
  exit 1
fi
if [ -z "${drupal_user}" ] || [[ $(id -un "${drupal_user}" 2> /dev/null) != "${drupal_user}" ]]; then
  printf "*************************************\n"
  printf "* Error: Please provide a valid user. *\n"
  printf "*************************************\n"
  print_help
  exit 1
fi
cd $drupal_path
printf "Changing ownership of all contents of "${drupal_path}":\n user => "${drupal_user}" \t group => "${httpd_group}"\n"
chown -R ${drupal_user}:${httpd_group} .
printf "Changing permissions of all directories inside "${drupal_path}" to "rwxr-x---"...\n"
find . -type d -exec chmod u=rwx,g=rx,o= '{}' \;
printf "Changing permissions of all files inside "${drupal_path}" to "rw-r-----"...\n"
find . -type f -exec chmod u=rw,g=r,o= '{}' \;
printf "Changing permissions of "files" directories in "${drupal_path}/sites" to "rwxrwx---"...\n"
cd sites
find . -type d -name files -exec chmod ug=rwx,o= '{}' \;
printf "Changing permissions of all files inside all "files" directories in "${drupal_path}/sites" to "rw-rw----"...\n"
printf "Changing permissions of all directories inside all "files" directories in "${drupal_path}/sites" to "rwxrwx---"...\n"
for x in ./*/files; do
    find ${x} -type d -exec chmod ug=rwx,o= '{}' \;
    find ${x} -type f -exec chmod ug=rw,o= '{}' \;
done
echo "Done setting proper permissions on files and directories"
Copy the code above to a file, name it "fix-permissions.sh" and run it as follows:
sudo bash fix-permissions.sh --drupal_path=your/drupal/path --drupal_user=your_user_name

Note: The server group name is assumed "www-data", if it differs use the --httpd_group=GROUP argument.

2

इसके अलावा, यदि आप फास्टस्कैजी चला रहे हैं, तो php उपयोगकर्ता के रूप में चलता है, और सभी फाइलों तक पहुंच होगी जो उपयोगकर्ता के पास तब तक होती है जब तक कि आप जानबूझकर इससे बचने की कोशिश नहीं करते हैं।


1

इससे मुझे अपने OSX अनुमति मुद्दों के साथ मदद मिली। मुझे यह प्रोटोप्लाज्म उपयोगकर्ता द्वारा https://www.drupal.org/node/244924#comment-3741738 में मिला । मैं एक प्रवास के बाद मुद्दे होने की तरह था।

[root@localhost]cd /path_to_drupal_installation/sites
[root@localhost]find . -type d -name files -exec chmod ug=rwx,o= '{}' \;
[root@localhost]find . -name files -type d -exec find '{}' -type f \; | while read FILE; do chmod ug=rw,o= "$FILE"; done
[root@localhost]find . -name files -type d -exec find '{}' -type d \; | while read DIR; do chmod ug=rwx,o= "$DIR"; done

-3

सुरक्षा समीक्षा नामक एक मॉड्यूल है जो यह जांचता है कि आपकी साइट सुरक्षित है या नहीं। मुझे साइट अनुमतियाँ सेट करने के लिए एक बहुत अच्छा लिंक भी मिला ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.